【问题标题】:Split multiple strings into a list of objects in C#将多个字符串拆分为 C# 中的对象列表
【发布时间】:2016-02-14 00:17:40
【问题描述】:

我有以下代码:

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

【问题讨论】:

  • 分割的长度是否始终相同?
  • 查看Enumerable.Zip

标签: c# string linq list ienumerable


【解决方案1】:

你可以使用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 拆分为一个字符串数组,然后将Zip 该数组与另一个从s2 创建的数组分开。这将根据第三个参数创建一个元素集合——在这种情况下,它是Info 对象的构造函数。所以基本上你只是得到Info 项目的集合?
  • @sab669:是的,但不是一个集合。目前它只是一个查询。如果你想要一个集合,你需要附加ToListToArrayEnumerable.Zip 同时枚举两个序列并返回相同索引的项。
  • 当我需要三个相同大小的拆分字符串时会发生什么?信息现在有 3 个字段。字符串 s1 = "a,b";字符串 s2 = "1,2";字符串 s3 = "G,J";
  • 我更多的意思是collection只是你拥有一堆对象的“通用”英文术语。但从技术上讲,我想我不能 100% 确定 Collection / ICollection 类 + 接口与 IEnumerable 之间的区别。不确定何时使用其中一种。
  • @user3716892 您应该能够再次将InfoSrcs3 压缩在一起,然后分配第三个属性?我相信蒂姆有更好的解决方案。 Zip 表示第一个和第二个参数不必是同一类型,所以它不应该是一个问题。
【解决方案2】:

假设每个列表中的项目数相等,看起来您正在尝试将它们 Zip 放在一起...

s1.Split(',').Zip(s2.Split(','), (name, num) => new Info{Name = name, Num = num})

【讨论】:

  • 应该是:IEnumerable&lt;Info&gt; InfoSrc = s1.Split(',').Zip(s2.Split(','), (a, b) =&gt; new Info { Name = a, Num = b });
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多