Tablica – Importowanie danych z pliku cz.2

Tablica – Importowanie danych z pliku cz.2

Jeśli sprubujemy teraz uruchomić aplikację, to ona nie zadziała dostaniemy wyjątek NullReferenceException w miejscu, w którym chcemy iterować nasze miasta z tablicy miast a to dla tego że nie mamy jeszcze zaimplementowanej metody ReadFirstNCitys która ma pobierać miasta z pliku w tej chwili metoda zwraca tylko null.

Przejdźmy zatem do metody ReadFirstNCitys i napiszmy potrzebny nam kod.

public City[] ReadFirstNCitys(int nCitys)
{
   City[] citys = new City[nCitys];

   using (StreamReader sr = new StreamReader(_csvFilePath))
   {
      sr.ReadLine();

      for (int i = 0; i < nCitys; i++)
      {
         string csvLine = sr.ReadLine();
         citys[i] = ReadCityFromCsvLine(csvLine);
      }
   }

   return citys;
}

Co tutaj robimy. Pierwsze tworzymy instancję tablicy miast dokładnie tylu ile przekazujemy w parametrze do metody. Następnie tworzymy instancję StreamReadera, który jest typem zapewnianym przez Microsoft do odczytu plików tekstowych.

StreamReadera jest w przestrzeni nazw System.IO. Musimy podać StreamReaderowi ścieżkę do pliku do odczytania, która jest przechowywana w polu csvFilePath

StreamReader ma metodę o nazwie ReadLine, która odczytuje kolejną linię tekstu z pliku i zwraca to, co jest odczytane jako string.

Pamiętaj, że pierwszy wiersz naszego pliku CSV to wiersz nagłówka, który możemy zignorować, więc po prostu wywołuję ReadLine, ale nie robię nic z wynikiem.

Potem mamy pętlę „for”, aby przeczytać, tyle miast ile jest przekazane w parametrze nCitys. Za każdym razem w pętli pobieram następny wiersz z pliku za pomocą StreamReader.ReadLine(), a następnie analizuję ten wiersz w metodzie ReadCityFromCsvLine() której jeszcze nie mamy i zaraz ją napiszemy, aby parsować pojedynczą linię z pliku do instancji miasta. I na koniec metoda zwraca tablicę miast.

Ponieważ każda linia / wiersz pliku CSV zawiera dane dla jednego miasta, oczywistym krokiem w importowaniu pliku danych będzie konwersja pojedynczej linii z pliku do instancji jednego miasta.

Napiszmy teraz metodę ReadCityFromCsvLine() aby to zrobić.

public City ReadCityFromCsvLine(string csvLine)
{
   string[] parts = csvLine.Split(',');

   string cityName = parts[0];
   string cityCode = parts[1];
   string country = parts[2];
   int totalPopulation = int.Parse(parts[3]);
   int menPopulation = int.Parse(parts[4]);
   int womanPopulation = int.Parse(parts[5]);

   return new City(cityName, cityCode, country, totalPopulation, menPopulation, womanPopulation);
}

Metoda jako argument przyjmuje ciąg znaków, który będzie zawartością wiersza pliku i zwraca instancję miasta, którą odczytaliśmy z linii pliku csv. Więc jaka jest tutaj logika?

Bardzo Prosta. Każda linia pliku CSV zawiera nazwę miasta, kod, kraj, całkowita populacja tego miasta, populacja menzczyzn tego miasta, populacja kobiet tego miasta, oddzielone przecinkami, więc ta metoda musi podzielić ciąg, który został odczytany wszędzie tam, gdzie zawiera przecinek, abyśmy otrzymali sześć oddzielnych ciągów, reprezentujących parametry wymagane przez konstruktor miasta.

I dokładnie to robi ta metoda, string.Split(). Jest to metoda do stringów, którą Microsoft udostępnił do dzielenia stringów i tutaj doskonale pasuje do naszych celów. Metoda split analizuje coś, co wygląda jak pojedynczy przecinek.
Argument mówi metodzie Split, który znak będzie separatorem, czyli znakiem oddzielającym pola. W tym przypadku separatorem jest przecinek, ale w innym scenariuszu może to być znak tabulacji lub średnik i tak dalej.
Split podzieli ciąg, gdziekolwiek zobaczy znak separatora, i zwróci wynik, i tutaj jest interesująca rzecz.

To, co zwraca, to jest tablica ciągów. Widzisz, string.Split pobiera jeden duży ciąg i zwraca potencjalnie wiele mniejszych ciągów. Jak inaczej może zwrócić wiele innych ciągów niż w kolekcji. Kolekcje są wszędzie. Teraz jest łatwo.

Tablica zwrócona przez string.Split będzie zawierać szesc stringów odpowiadających każdej kolumnie w każdej linii CSV. Pierwsza część to miaso, druga to kod, trzecia to kraj,a czwarta to całkowita populacja tego miasta i tak dalej…

Oczywiście dostęp do tych danych uzyskujemy przy użyciu składni nawiasu kwadratowego i pamiętamy, że tablica jest indeksowana do zera. I musimy przekonwertować wszystkie populację na liczbę całkowitą i dla bezpieczeństwa używamy int.parse, co spowoduje zgłoszenie wyjątku, jeśli z jakiegokolwiek powodu te pola nie mogą zostać przeanalizowane jako liczba całkowita.

Proste, co?  Właściwie ten kod jest zbyt prosty.

Jeszcze potrzebujemy pliku population.csv

City Name,City Code,Country,Total population,Men population,Women population
Mazowieckie,MAZ,Polska,5411446,2589469,2821977
Slaskie,SLA,Polska,4524091,2180662,2343429
Wielkopolskie,WLK,Polska,3495470,1700647,1794823
WielkopolskieTest,WLK,Polska,3495470,1700647,1794823
Malopolskie,MLP,Polska,3404863,1652663,1752200
Dolnoslaskie,DOL,Polska,2899986,1394399,1505587
Lodzkie,LDZ,Polska,2460170,1172228,1287942
LodzkieTest,LDZ,Polska,2460170,1172228,1287942
PomorskieTest,POM,Polska,2337769,1138351,1199418
Pomorskie,POM,Polska,2337769,1138351,1199418
Podkarpackie,PKR,Polska,2127462,1041890,1085572
Lubelskie,LBL,Polska,2112216,1023626,1088590
Kujawsko-pomorskie,K-P,Polska,2074517,1005361,1069156
Zachodniopomorskie,ZPM,Polska,1698344,825659,872685
Warminsko-mazurskie,W-M,Polska,1425967,697504,728463
Swietokrzyskie,SWI,Polska,1237369,603304,634065
Podlaskie,PDL,Polska,1179430,574786,604644
Lubuskie,LBU,Polska,1013031,492984,520047
Opolskie,OPO,Polska,984345,476017,508328

I teraz doszliśmy do końca i możemy uruchomić nasz program!

Już prawie skończyliśmy, ale jest jeszcze jedna ostatnia rzecz, którą chcę rozwiązać.
Sposób wyświetlania tych populacji jest okropny do odczytania. Ludność Mazowieckiego wynosi w rzeczywistości 5,4 miliona, ale to, co jest tutaj wyświetlane, wygląda jak jedna duża liczba. Musisz się naprawdę skoncentrować, aby dowiedzieć się, jakie są te populacje, więc sformatujmy trochę ten wynik.

Console.WriteLine($"{city.TotalPopulation:### ### ###} : {city.CityCode} : {city.CityName}");

Całościowe omówienie tematu kolekcji (tablica, lista, kolejka, stos, słownik).
Wiele przydatnych wskazówek i dobrych praktyk dostępne jest na kursie:

https://dev-hobby.pl/kursy/c-wprowadzenie-do-kolekcji/


17 comments

  1. I read a great article with pleasure, I hope it will continue Sib Corbie Brandie

  2. Here is a great Weblog You might Come across Interesting that we Encourage You Elaine Rodger Friedly

  3. we prefer to honor several other net web-sites around the web, even if they arent linked to us, by linking to them. Under are some webpages really worth checking out Darcy Scottie Geer

  4. Only wanna state that this is extremely helpful, Thanks for taking your time to write this. Genia Udell Branca

  5. Hi, i read your blog occasionally and i own a similar one and i was just curious if yyou get a lot of spam responses? Darda Thorpe Ferro

  6. Wow! After all I got a blog from where I be able to genuinely take useful data concerning my study and knowledge. Melodie Shelby Kidd

  7. whoah this weblog is excellent i love reading your posts. Keep up the good work! You understand, many individuals are searching round for this information, you can aid them greatly. | Meta Jory Huber

  8. I would like to thank you for the efforts you have put in writing this blog. I am hoping the same high-grade website post from you in the upcoming as well. In fact your creative writing abilities has inspired me to get my own web site now. Really the blogging is spreading its wings quickly. Your write up is a great example of it. Britteny Clem Fidel

  9. Excellent beat ! I wish to apprentice while you amend your website, how could i subscribe for a blog site? The account helped me a acceptable deal. I had been tiny bit acquainted of this your broadcast provided bright clear concept Gene Hamel Subak

  10. Hiya, I am really glad I have found this information. Today bloggers publish only about gossip and web stuff and this is actually irritating. A good website with exciting content, that is what I need. Thank you for making this website, and I will be visiting again. Do you do newsletters by email? Sophey Booth Shull

  11. I have been checking out some of your articles and i can state pretty nice stuff. I will surely bookmark your site. Melli Aloysius Usanis

  12. Hi there to every one, the contents existing at this website are really amazing for people experience, well, keep up the good work fellows. Sandy Alon Joey

  13. Wonderful post! We are linking to this great post on our website. Keep up the great writing. Robyn Boy Barcellona

  14. Członkowie rodziny zawsze mówią, że zabijam
    mój czas tutaj w sieci, z wyjątkiem tego, że wiem, że codziennie rozwijam znajomość, czytając takie dobre artykuły lub recenzje.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *