将值从一个IEnumerable <type1>添加到其他IEnumerable <type2>

时间:2017-09-29 07:22:39

标签: c# linq

让我们说我们有两种对象类型:

class Type1
{
    public int Value {get;set;}
}

class Type2
{
    public int Val {get; set;}
}

我们有两个IEnumerable:

IEnumerable<Type1> type1col;
IEnumerable<Type2> type2col;

我想要的是:每个type1col元素Value属性值都会添加足够的type2col Val属性值。

我们可以说两个IEnumerables总是具有相同的长度。

现在我正在使用它:

for (int i = 0; i < type1col.Count(); i++)
{
    type1col.ElementAt(i).Value += type2col.ElementAt(i).Val;
}

但有没有更好(更快和更短)的方法来做同样的事情?

3 个答案:

答案 0 :(得分:4)

您可以使用IEnumerable.Zip

var type1Col = type1Col.Select(x => x.Value)
    .Zip(type2Col.Select(x => x.Value), (x, y) => x + y)
    .Select(x => new Type1 { Value = x });

但是,由于您已经拥有简单列表,因此您还可以使用经典循环并使用索引器而不是IEnumerable.ElementAt

for(int i = 0; i < type1Col.Count; i++)
{
    type1Col[i].Value += typeo2Col[i];
}

答案 1 :(得分:4)

将两者一起枚举会更快

[Benchmark]
public static void Enumerator()
{
    using (var enumerator1 = Type1S.GetEnumerator())
    {
        using (var enumerator2 = Type2S.GetEnumerator())
        {
            while (enumerator1.MoveNext() && enumerator2.MoveNext())
            {
                enumerator1.Current.Value += enumerator2.Current.Val;
            }
        }
    }
}

enter image description here

答案 2 :(得分:1)

如果你想对序列的元素进行就地修改而不是使用Zip()创建新序列的开销,你可以这样做:

public static void Combine<T1, T2>(IEnumerable<T1> target, IEnumerable<T2> modifyier, Action<T1, T2> modify)
{
    using (var seq1 = target.GetEnumerator())
    using (var seq2 = modifyier.GetEnumerator())
    {
        while (seq1.MoveNext() && seq2.MoveNext())
        {
            modify(seq1.Current, seq2.Current);
        }
    }
}

您可以这样使用:

IEnumerable<Type1> typecol1 = new List<Type1>{new Type1{Value = 1 }, new Type1 { Value = 2 } };
IEnumerable<Type2> typecol2 = new List<Type2>{new Type2{Val = 3}, new Type2{ Val = 4 } };

Combine(typecol1, typecol2, (type1, type2) => type1.Value += type2.Val);

foreach (var item in typecol1)
{
    Console.WriteLine(item.Value);
}