将多个字符串拆分为C#对象列表

5

我有以下代码:

public class Info
{
  public string Name;
  public string Num;
}

string s1 = "a,b";
string s2 = "1,2";

IEnumerable<Info> InfoSrc =
    from name in s1.Split(',')
    from num in s2.Split(',')
    select new Info()
    {
        Name = name,
        Num = num
    };

List<Info> listSrc = InfoSrc.ToList();

我希望我的listSrc结果包含两个Info项,其NameNum属性分别为:
a, 1
b, 2

然而,我展示的代码会得到四个项目:
a, 1
a, 2
b, 1
b, 2

分割的长度会一直相同吗? - Johan
3
请查阅 Enumerable.Zip 方法。 - Kvam
2个回答

6
你可以使用 Enumerable.Zip:
IEnumerable<Info> InfoSrc = s1.Split(',')
    .Zip(s2.Split(','), (name, num) => new Info(){ Name = name, Num = num });

如果您需要将两个以上的集合映射到属性,您可以使用匿名类型将第二个和第三个集合链接在一起,使用多个 Zip 进行链式操作:
IEnumerable<Info> InfoSrc = s1.Split(',')
    .Zip(s2.Split(',').Zip(s3.Split(','), (second, third) => new { second, third }),
        (first, x) => new Info { Name = first, Num = x.second, Prop3 = x.third });

以下是希望更易读的版本:

var arrays = new List<string[]> { s1.Split(','), s2.Split(','), s3.Split(',') };
int minLength = arrays.Min(arr => arr.Length);  // to be safe, same behaviour as Zip
IEnumerable<Info> InfoSrc = Enumerable.Range(0, minLength)
 .Select(i => new Info
 {
     Name = arrays[0][i],
     Num = arrays[1][i],
     Prop3 = arrays[2][i]
 });

为了确保我理解正在发生的事情,基本上您将s1拆分为字符串数组,然后将该数组与从s2创建的另一个数组进行Zip。这将根据第三个参数创建元素的集合--在这种情况下是Info对象的构造函数。所以基本上您只是得到了一个Info项的集合? - sab669
@sab669:是的,但不是一个集合。目前它只是一个查询。如果你想要一个集合,你需要附加 ToListToArrayEnumerable.Zip 同时枚举两个序列,并返回在相同索引处的项。 - Tim Schmelter
当我需要三个等大小的拆分字符串时会发生什么?现在信息有3个字段。 字符串s1 =“a,b”; 字符串s2 =“1,2”; 字符串s3 =“G,J”。 - user3716892
我更多的是指集合只是你有一堆对象的“通用”英语术语。但从技术上讲,我不确定Collection / ICollection类+接口与IEnumerable之间的区别。不确定何时使用其中之一。 - sab669
@user3716892 你只需要将 InfoSrcs3 再次压缩在一起,然后分配第三个属性即可。虽然我相信Tim有更好的解决方案。Zip 表示第一个和第二个参数不必是相同类型,因此这不应该是问题。 - sab669
@user3716892:其中一种方法是像我在答案中展示的那样将它们链接起来。但我必须承认这不再很易读。另一种方法是将string[]放入List<string[]>string[][]中,然后您可以通过索引访问它们。如果您愿意,我可以向您展示这种方法。 - Tim Schmelter

5
假设每个列表中的项目数相等,看起来您正在尝试将它们Zip在一起...
s1.Split(',').Zip(s2.Split(','), (name, num) => new Info{Name = name, Num = num})

应该是:IEnumerable<Info> InfoSrc = s1.Split(',').Zip(s2.Split(','), (a, b) => new Info { Name = a, Num = b }); - Amir Popovich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接