【问题标题】:how to retrieve lines from csv to sub list如何从 csv 检索行到子列表
【发布时间】:2016-07-09 12:06:36
【问题描述】:

我有一个巨大的 csv 文件,其中包含如下行:

CityName    CityCode    DistrictName    ZipCode
Adana       1           Çukurova        1780
Adana       1           Feke            1660
Adana       1           İmamoğlu        1700

您认为只有 Districtname 和 zipcode 列值在大多数行中更改前两行相同,因此我对此数据的模型定义:

public class City
    {
        public string name { get; set; }
        public int cityCode { get; set; }

        public List<District> districts { get; set; }
    }

    public class District
    {
        public string district { get; set; }
        public string zipCode { get; set; }
    }

现在我想知道如何读取这些数据并将其加载到列表中:

string[] lines = System.IO.File.ReadAllLines(fullName);
            IQueryable<City> cities = lines.Skip(1).Select(l => new City
            {
                name = l.Split(',')[0],
                cityCode = Convert.ToInt32(l.Split(',')[1]),
                ..
            }).AsQueryable();

我怎样才能做到这一点?

【问题讨论】:

  • 使用我的 CSV 阅读器,它使用 oledb 读取数据表。 stackoverflow.com/questions/30129406/…
  • 谢谢,但这只会读取列名,如何在列表中填写行?
  • 它使用 oledb 将所有内容读入数据表。 csv 文件中有空行吗?
  • 不,我不知道,foreach 循环中只发生了 4 次迭代。我怎样才能看到内容?
  • foreach 只是为列名添加下划线。表的行是对 csv 数据库的查询。是的,从技术上讲,csv 是一个数据库。

标签: c# csv


【解决方案1】:

csv 文件已更改为“|”分开

使用 Linq 完成代码

public class City
{
    public string name { get; set; }
    public int cityCode { get; set; }
    public District distict { get; set; }
    public List<District> districts { get; set; }
    public static City Convert(string strCity)
    {
        var strArr = strCity.Split('|');
        var cityObj = new City();
        cityObj.name = strArr[0];
        cityObj.cityCode =int.Parse(strArr[1]);
        cityObj.distict = new District() {district= strArr[2], zipCode = strArr[3] };

        return cityObj;
    }
}

public class District
{
    public string district { get; set; }
    public string zipCode { get; set; }
    public override string ToString()
    {
       return this.district + ":" + this.zipCode;
    }
}

public class LinqTest
{

    public void ReadCsv()
    {
        var data = File.ReadLines(".\\test.csv").Skip(1)
            .Select(x => City.Convert(x)).GroupBy(x => new { Name = x.name, Code = x.cityCode })
            .Select(x => new City() { name = x.Key.Name, cityCode = x.Key.Code, districts = x.Select(item => item.distict).ToList() });

        foreach (var item in data)
        {
            System.Diagnostics.Debug.WriteLine($"Name:{item.name} Code: {item.cityCode} Districts: {string.Join(",", item.districts)}");
        }
    }
}

【讨论】:

  • csv 文件已更改为“|”分开
  • 太棒了.. 谢谢
【解决方案2】:

这样做有什么问题?您可以简单地逐行阅读,将所需的数据检查包括在内,然后将所有结构插入到简单的城市列表中。像这样,我离开了他需要 cmets:

List<City> listWithCities = new List<City>(); //create a list of cities
using(StreamReader file = new StreamReader(fullName))//open a reader
{
    string line = String.Empty;
    while((line = file.ReadLine()) != null) //loop lines
    {
        if(!line.Contains(',') || line == String.Empty || line.IndexOf("//") == 0)  //to avoid comments, or empty lines, or lines without separator
            continue;

        if(line.Contains("//"))
            line = line.Substring(0, line.Length - line.Substring(line.IndexOf("//")).Length); //skipping comments of type '//' if you need

        string[] parts = line.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);

        if(parts.Length < 4) //there are less than 4 parts, so it's not a valid data line? You may skip that if you want
            continue;

        int indexOfPossiblyExistingItem = Array.FindIndex(listWithCities.ToArray(), cit => cit.name == parts[0]);
        if(indexOfPossiblyExistingItem != -1) //the city exists
        {
            listWithCities[indexOfPossiblyExistingItem].districts.Add(new District {district = parts[2], zipCode = parts[3]}); //adding a new destrict ot the list
        }
        else //city does not exist
        {
            listWithCities.Add(new City{name = parts[0], cityCode = Convert.ToInt32(parts[1]), disricts = new List<District>(new District[] {new District{district = parts[2], zipCode = parts[3]})}}) //adding new city + 1 disctrict in the list
        }
    }
    file.Close();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-01
    • 2014-05-14
    • 1970-01-01
    • 2019-12-07
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    相关资源
    最近更新 更多