HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpModerate

Combining List<>.ForEach and List<>.Zip

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
combiningandzipforeachlist

Problem

I have three lists, and I need to operate on the ith element of each list simultaneously.

private void TripleForEach(IEnumerable a1, IEnumerable a2, IEnumerable a3, Action x)
{
    a3.Zip(a2, (t3, t2) => Tuple.Create(t2, t3)).Zip(a1, (t23, t1) => Tuple.Create(t1, t23.Item1, t23.Item2)).ToList().ForEach(z => x(z.Item1, z.Item2, z.Item3));
}


Any better way to do this? Creating and pulling apart those temporary Tuples smells bad to me.

Solution

I agree, the temporary tuples are a code smell. They carry a performance overhead, but worse, they obscure the purpose of the code. Here is a way of achieving the goal by working directly on the enumerators.

private static void TripleForEach(
        IEnumerable first,
        IEnumerable second,
        IEnumerable third,
        Action action)
{
    using (IEnumerator e1 = first.GetEnumerator())
    using (IEnumerator e2 = second.GetEnumerator())
    using (IEnumerator e3 = third.GetEnumerator())
    {
        while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext())
        {
            action(e1.Current, e2.Current, e3.Current);
        }
    }
}

Code Snippets

private static void TripleForEach<TFirst, TSecond, TThird>(
        IEnumerable<TFirst> first,
        IEnumerable<TSecond> second,
        IEnumerable<TThird> third,
        Action<TFirst, TSecond, TThird> action)
{
    using (IEnumerator<TFirst> e1 = first.GetEnumerator())
    using (IEnumerator<TSecond> e2 = second.GetEnumerator())
    using (IEnumerator<TThird> e3 = third.GetEnumerator())
    {
        while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext())
        {
            action(e1.Current, e2.Current, e3.Current);
        }
    }
}

Context

StackExchange Code Review Q#53855, answer score: 11

Revisions (0)

No revisions yet.