7
\$\begingroup\$

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

private void TripleForEach<T1, T2, T3>(IEnumerable<T1> a1, IEnumerable<T2> a2, IEnumerable<T3> a3, Action<T1, T2, T3> 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.

\$\endgroup\$
11
\$\begingroup\$

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<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);
        }
    }
}
\$\endgroup\$
1
\$\begingroup\$

If your code is dependent on multiple collections that are being correlated by index, then they should be of a type that allows access by index, not IEnumerable. If the code doesn't really look right with for loops, it's probably because the multiple collections were all projected from the same source list and using the index is an easy way to correlate them back together. If that is the case consider reworking the logic that creates the lists in the first place--it may make sense to project to one working list of a type that contains all of the information needed by all 3 areas of code.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.