pitersmx
pitersmx

Reputation: 957

Add values from one IEnumerable<Type1> to other IEnumerable<Type2>

Let's say that we have two object types:

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

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

And we have two IEnumerable's for them:

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

What I want to have: each of type1col elements Value property value would have adequate type2col Val property value added.

We can say that both IEnumerables will have the same length always.

For now I am using this:

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

but is there any better (faster & shorter) approach to do the same?

Upvotes: 2

Views: 97

Answers (3)

Kevin Smith
Kevin Smith

Reputation: 14456

Enumerating both together would be faster

[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

Upvotes: 4

Matthew Watson
Matthew Watson

Reputation: 109762

If you want to do an in-place modification of the elements of a sequence rather than having the overhead of creating a new sequence using Zip() you could do something like this:

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);
        }
    }
}

Which you would use like this:

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);
}

Upvotes: 1

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37070

You can use 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 });

But as you allready have simple lists you can also use a classic loop and use indexers instead of IEnumerable.ElementAt:

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

Upvotes: 4

Related Questions