Lista part.5 – Import danych z pliku.

Lista part.5 – Import danych z pliku.

Teraz nadszedł czas na demo. Kiedy omawialiśmy tablice stworzyłem demo, które wyświetlało 7 pierwszych miast zaimportowanych z pliku CSV. Teraz zamierzam zmodyfikować to demo, aby zamiast importować tylko 7 miast, importować i wyświetlać wszystkie miasta. Mamy nasz CsvReader.

public class CsvReader
{
  private string _csvFilePath;

  public CsvReader(string csvFilePath)
  {
    _csvFilePath = csvFilePath;
  }

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

    using (StreamReader streamReader = new StreamReader(_csvFilePath))
    {
      // read header line
      streamReader.ReadLine();

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

    return citys;
  }

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

    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 womenPopulation = int.Parse(parts[5]);

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

CsvReader jest odpowiedzialny za czytanie miast. I metodę, którą musimy zmienić, to ReadFirstNCitys. Ta metoda oczywiście musi teraz odczytać wszystkie miasta, więc najpierw zmienię nazwę metody, aby odzwierciedlić jej nowy cel.

public City[] ReadAllCiyts(int nCitys)

A ponieważ importuję wszystko, nie potrzebuję już argumentów, aby powiedzieć, ile miast chcemy.

public City[] ReadAllCiyts()

Poza tym oczywiście musimy zwrócić listę miast, a nie tablicę miast.

public List<City> ReadAllCiyts()

To samo dotyczy zmiennej miasta.

List<City> citys = new List<City>();

Ta zmienna miasta ” citys[i] ” również musi się zmienić. Tutaj próbuje zastąpić element listy. Ale składnia do zamiany elementów dla listy jest dokładnie taka sama jak i dla tablicy. Więc ten wiersz jest poprawny pod względem składniowym. Ale to tutaj nie zadziała, ponieważ lista zaczyna się pusta, więc nie ma elementów do zastąpienia. Zamiast tego musimy dodać każde miasto do listy, powiększając ją.
Teraz to zrobimy.

citys.Add(ReadCityFromCsvLine(csvLine));

i pętla musi przejść do końca pliku, a nie zatrzymywać się po n miastach.

string csvLine;
while((csvLine = streamReader.ReadLine()) != null)
{ 
   citys.Add(ReadCityFromCsvLine(csvLine));
}

Teraz to jest pętla while, a nie pętla for.

Logika oparta jest na funkcji StreamReader.ReadLine. ReadLine zwróci null, jeśli stwierdzi, że nie może już czytać danych, ponieważ osiągnął już koniec pliku. Chodzi o to, że czytamy dalej, dopóki ReadLine nie zwróci wartości null.

Powinniśmy także sprawdzić metodę Main, która wyświetla miasta. Program VisualStudio zaznacza nam tutaj błąd kompilacji. Jest tak, ponieważ w tej metodzie miasta są zadeklarowane jako tablica miast, a ReadAllCitys zwraca listę miast i nie jest wymagany żaden parametr. Naprawmy to.

List<City> citys = csvReader.ReadAllCiyts();

Teraz jest w porządku, a kluczową rzeczą, którą należy zauważyć tutaj, jest to, że nie musimy niczego zmieniać w tej pętli foreach. Foreach działa dokładnie tak samo w przypadku listy jak i przypadku tablicy i prawdopodobnie w tym miejscu możesz zobaczyć piękno kolekcji.

Mimo że różne kolekcje mają różne możliwości, Microsoft starannie je zaprojektował,
aby bardzo często działał ten sam kod dla każdego typu kolekcji. Teraz możemy uruchomić nasz kod, aby wyświetlić listę wszystkich miast. I teraz mamy wyświetlane wszystkie miasta.

I cały kod po modyfikacjach.

public class CsvReader
{
  private string _csvFilePath;

  public CsvReader(string csvFilePath)
  {
    _csvFilePath = csvFilePath;
  }

  public List<City> ReadAllCiyts()
  {
    List<City> citys = new List<City>();

    using (StreamReader streamReader = new StreamReader(_csvFilePath))
    {
      // read header line
      streamReader.ReadLine();

      string csvLine;
      while((csvLine = streamReader.ReadLine()) != null)
      { 
        citys.Add(ReadCityFromCsvLine(csvLine));
      }
    }

    return citys;
  }

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

    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 womenPopulation = int.Parse(parts[5]);

    return new City(cityName, cityCode, country, totalPopulation, menPopulation, womenPopulation);
  }
}
class Program
{
   static void Main(string[] args)
   {
      string filePath = @"C:\Users\user\repos\population.csv";

      CsvReader csvReader = new CsvReader(filePath);

      List<City> citys = csvReader.ReadAllCiyts();

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

Cały kod do kursu na githubie:

https://github.com/mariuszjurczenko/BeginningCsharpCollections

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/

Dodaj komentarz

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