我正在使用CsvHelper
解析CSV文件。我正在使用helper.GetRecords<dynamic>().ToList();
返回一个List<ExpandoObject>
。
列表中的每个ExpandoObject
代表CSV文件中的一行,而ExpandoObject
的每个属性对应于CSV文件的一列,其中该属性是根据列标题来命名的。>
编辑,我收到许多不同的CSV文件,每个文件都有不同的标题和值。这里的想法是让Controller返回CSV文件中的标头列表以及在每一列中找到的所有唯一值。
示例(CSV数据)
ID, Name, State, Age
1,Mickey,FL,50
2,Minnie,FL,48
3,Donald,AK,48
我会有这样的东西(List<IDictionary<string,object>>
var results = helper.GetRecords<dynamic>();
var item = (IDictionary<string,object>) results.First();
foreach(var prop in (IDictionary<string,object>)item){
console.WriteLine($"{prop.Key} : {prop.Value}");
}
//ID : 1
//Name: Mickey
//State: FL
//Age: 50
我要做什么
由于IDictionary<string,object>
中的每个List
都包含同一组Keys
,因此我想像这样使用Group<key,List<uniquevalues>>
:
Group Key: "ID"
Values: ["1","2","3"]
Group Key: "Name"
Values: ["Mickey","Minnie","Donald"]
Group Key: "State"
Values: ["FL","AK"]
Group Key: "Age"
Values: ["50","48"]
注意,解决方案不一定非要是Group,它可以是IDictionary<key, List<unique value>>
。
答案 0 :(得分:2)
高级解决方案: 使用投影(选择)创建所需的4个新对象(可以是匿名对象或预定义对象)。 然后,可以对相同对象使用联合运算符来删除重复项。 (如果您使用匿名类型,则无需传递自定义的Equality比较器)
答案 1 :(得分:0)
由于您有一组定义明确的标题,因此可以创建一个代表记录的类,并按如下方式读取它:
var results = helper.GetRecords<Person>();
在这里,Person
是代表您的CSV
列的类,如下所示:
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public string State { get; set; }
public int Age { get; set; }
}
然后,在阅读时,您可以遍历每个属性并创建一个唯一值列表。
var list = new Dictionary<string, dynamic>();
foreach (var prop in typeof(Person).GetProperties())
{
list.Add(prop.Name, results.Select(x => prop.GetValue(x)).Distinct());
}
答案 2 :(得分:0)
您要寻找的是在按每个键/属性及其关联值分组之前,将列表变平。这将产生您想要的结果。
var group = results
.SelectMany(r => r)
.GroupBy(g => g.Key)
.Select(g => new {
Key = g.Key,
Values = string.Join(",", g.Select(r => r.Value))
});
foreach(var r in group)
Console.WriteLine("Key: " + r.Key + ", Values: " + r.Values);
HTH