将匹配的csv行读入List <dictionary>

时间:2016-04-16 03:34:49

标签: c# linq csv

我正在尝试读取结构化csv文件的标题行,查找与参数匹配的行,然后将匹配的行作为列表对象列表返回为List [Dictionary [Header,RowColumnValue]]。

我希望能够将List [x] [key] Dictionary值分配给表单中的控件。

以下基本上是伪代码,因为它不起作用,但希望这个想法很清楚。我假设有一种方法可以通过LINQ来简化它:

public static List<Dictionary<string, string>> RowEntries(string LocationAndCategory)
{
    var lines = File.ReadAllLines(@"C:\MyFile.csv");
    var header = lines.First().Split(',');          
    List<string> rowsList = lines
        .Where(line => line.Split(',')[0] + " " + line.Split(',')[1] == LocationAndCategory)
        .Select(line => line).ToList();
    int y = 0;
    var listDictionaries = new { List<Dictionary<string, string>>};
    foreach(string line in rowsList)
    {
        for (int x = 0; x <= header.Count<string>(); x++)
        {
            listDictionaries.Add(new Dictionary<string, string>);
            listDictionaries[y].Add(header[x], Split(rowsList[y], (','))[x]);
        }
        y++;
    }
    return listDictionaries;
}

2 个答案:

答案 0 :(得分:2)

使用LINQ可以这样做:

var result = lines
    .Skip(1)    //skip the header line
    .Where(line => line.Split(',')[0] + " " + line.Split(',')[1] == LocationAndCategory)

    //project the query to an enumerable of dictionary of (header,value)
    .Select(line => header.Select((h, i) => new { header = h, index = i })
                          .ToDictionary(o => o.header, o => line.Split(',')[o.index]))
    .ToList();

这是上面的更多查询样式版本:

var result = (from line in lines.Skip(1)
              let cols = line.Split(',')
              where cols[0] + " " + cols[1] == LocationAndCategory
              select
                header.Select((h, i) => new { header = h, index = i })
                      .ToDictionary(o => o.header, o => cols[o.index])
              ).ToList();

答案 1 :(得分:1)

从您的代码中,我了解您需要CSV中的每一行转换为Dictionary

public static List<Dictionary<string, string>> RowEntries(string LocationAndCategory)
{
    var lines = File.ReadAllLines(@"C:\MyFile.csv");
    var header = lines.First().Split(',');          
    int y=-1;

    return lines.Skip(1) //skip header.
                // Split string and take only first two strings to compare with LocationAndCategory.
                .Where(line => string.Join(" ",line.Split(',').Take(2)) == LocationAndCategory) 
                // Split each line by ',' and convert to dictionary.
                .Select(l=>l.Split(',').ToDictionary(x=> header[(++y)%header.Count()], x=>x))
                .ToList();      
}