C# 对象列表 c#
C# object to list c#
我正在读取一个 csv 文件,我想将第二列添加到与名称匹配的列所在的同一列表中。我检查下一行是否等于上一条记录,然后我循环查找匹配项的数组,但我不确定如何将该 internalList 添加回 class 对象。
is there a better way to do this?
计划
while ((s = sr.ReadLine()) != null)
{
string[] words = s.Split('\t');
if (previousrecord == words[0])
{
for (int i = 0; i < ALEComName.Count; ++i)
{
}
}
else
{
Name person = new Name();
person.Name = words[0];
List<SubName> internalList = new List<SubName>();
SubName AssociatedSub = new SubName { Name = words[1] };
internalList.Add(AssociatedSub);
person.AssociatedSub = internalList;
ALEComName.Add(Disease);
}
previousrecord = words[0];
Dto
public class Name
{
public string Name { get; set; }
public List<SubName> AssociatedSub { get; set; }
}
public class SubName
{
public string Name { get; set; }
}
}
CSV 文件
A A
B B
C A
C B
C C
D A
D B
您可以读取所有行,然后使用 Linq:
var data = File.ReadAllLines(@"c:\temp\sample.txt");
var names = data.Select(d => d.Split('\t'))
.Select(s => new { Name = s[0], SubName = s[1] })
.GroupBy(o => o.Name)
.Select(g => new Name()
{
Name1 = g.Key,
AssociatedSub = g.Select(v => new SubName() { Name = v.SubName }).ToList()
});
//This part is just to show the output
foreach (var name in names)
{
Console.WriteLine($"Name: {name.Name1}, AssociatedSub: {string.Join(",", name.AssociatedSub.Select(s => s.Name).ToArray())}");
}
输出:
Name: A, AssociatedSub: A
Name: B, AssociatedSub: B
Name: C, AssociatedSub: A,B,C
Name: D, AssociatedSub: A,B
我不得不将 属性 的名称更改为 Name1
,因为它是一个无效的语言结构。
您首先 select 拆分结果,然后创建一个具有 Name
和 SubName
属性的匿名类型,用于分组。最后,您 select 从分组的结果中创建实例。
这只是一个快速示例,因此请注意错误,例如 Split
未返回预期的零件数。
Linq 的方法非常好,我同意这个想法。如果你想要一种更保守的方式,我做了一个字典方法,它存储键值对。
class Program {
static void Main(string[] args) {
using(var file = new StreamReader(@"../file.csv")) {
var dict = new Dictionary<string, List<string>>();
List<string> split;
string line, key;
while((line = file.ReadLine()) != null) {
split = line.Select(l => new string(l, 1)).Where(l => l != " ").ToList();
key = split[0];
split.RemoveAt(0);
if(dict.ContainsKey(key)) {
dict.TryGetValue(key, out var values);
values.AddRange(split);
} else dict.Add(key, split);
}
foreach(KeyValuePair<string, List<string>> r in dict) {
foreach(var val in r.Value) {
Console.WriteLine("Main = {0}, Sub = {1}", r.Key, val);
}
}
}
}
}
我正在读取一个 csv 文件,我想将第二列添加到与名称匹配的列所在的同一列表中。我检查下一行是否等于上一条记录,然后我循环查找匹配项的数组,但我不确定如何将该 internalList 添加回 class 对象。
is there a better way to do this?
计划
while ((s = sr.ReadLine()) != null)
{
string[] words = s.Split('\t');
if (previousrecord == words[0])
{
for (int i = 0; i < ALEComName.Count; ++i)
{
}
}
else
{
Name person = new Name();
person.Name = words[0];
List<SubName> internalList = new List<SubName>();
SubName AssociatedSub = new SubName { Name = words[1] };
internalList.Add(AssociatedSub);
person.AssociatedSub = internalList;
ALEComName.Add(Disease);
}
previousrecord = words[0];
Dto
public class Name
{
public string Name { get; set; }
public List<SubName> AssociatedSub { get; set; }
}
public class SubName
{
public string Name { get; set; }
}
}
CSV 文件
A A
B B
C A
C B
C C
D A
D B
您可以读取所有行,然后使用 Linq:
var data = File.ReadAllLines(@"c:\temp\sample.txt");
var names = data.Select(d => d.Split('\t'))
.Select(s => new { Name = s[0], SubName = s[1] })
.GroupBy(o => o.Name)
.Select(g => new Name()
{
Name1 = g.Key,
AssociatedSub = g.Select(v => new SubName() { Name = v.SubName }).ToList()
});
//This part is just to show the output
foreach (var name in names)
{
Console.WriteLine($"Name: {name.Name1}, AssociatedSub: {string.Join(",", name.AssociatedSub.Select(s => s.Name).ToArray())}");
}
输出:
Name: A, AssociatedSub: A
Name: B, AssociatedSub: B
Name: C, AssociatedSub: A,B,C
Name: D, AssociatedSub: A,B
我不得不将 属性 的名称更改为 Name1
,因为它是一个无效的语言结构。
您首先 select 拆分结果,然后创建一个具有 Name
和 SubName
属性的匿名类型,用于分组。最后,您 select 从分组的结果中创建实例。
这只是一个快速示例,因此请注意错误,例如 Split
未返回预期的零件数。
Linq 的方法非常好,我同意这个想法。如果你想要一种更保守的方式,我做了一个字典方法,它存储键值对。
class Program {
static void Main(string[] args) {
using(var file = new StreamReader(@"../file.csv")) {
var dict = new Dictionary<string, List<string>>();
List<string> split;
string line, key;
while((line = file.ReadLine()) != null) {
split = line.Select(l => new string(l, 1)).Where(l => l != " ").ToList();
key = split[0];
split.RemoveAt(0);
if(dict.ContainsKey(key)) {
dict.TryGetValue(key, out var values);
values.AddRange(split);
} else dict.Add(key, split);
}
foreach(KeyValuePair<string, List<string>> r in dict) {
foreach(var val in r.Value) {
Console.WriteLine("Main = {0}, Sub = {1}", r.Key, val);
}
}
}
}
}