Using foreach to loop more than two list<string>

I'm trying to loop five list by merging them.

I know that this works fine

var zipped = letters.Zip(numbers, Tuple.Create);

 foreach (var tuple in zipped)
 {
     Console.WriteLine(tuple.Item1);
     Console.WriteLine(tuple.Item2);
 }

but i'm wondering I can use that same method, but with more list included.

Let's say I have the list numbers, letters, words, pictures and songs

How whould that loop look like then?

Jon Skeet
people
quotationmark

The simplest approach would probably be to reimplement Zip yourself multiple times, e.g.

public static IEnumerable<Tuple<T1, T2>> ZipTuple<T1, T2>(
    this IEnumerable<T1> source1,
    IEnumerable<T2> source2)

public static IEnumerable<Tuple<T1, T2, T3>> ZipTuple<T1, T2, T3>(
    this IEnumerable<T1> source1,
    IEnumerable<T2> source2,
    IEnumerable<T3> source3)

public static IEnumerable<Tuple<T1, T2, T3, T4>> ZipTuple<T1, T2, T3, T4>(
    this IEnumerable<T1> source1,
    IEnumerable<T2> source2,
    IEnumerable<T3> source3,
    IEnumerable<T3> source4)

The implementation will be tedious, but it's fairly simple to do.

Then you can just call:

var query = numbers.ZipTuple(letters, words, pictures, songs);

I'd probably implement each independently from scratch, but you could do it with one call to the "previous" ZipTuple and one call to Zip in each case, e.g.

public static IEnumerable<Tuple<T1, T2, T3>> ZipTuple<T1, T2, T3>(
    this IEnumerable<T1> source1,
    IEnumerable<T2> source2,
    IEnumerable<T3> source3)
{
    return source1
        .ZipTuple(source2)
        .Zip(source3, (t1, extra) => Tuple.Create(t1.Item1, t1.Item2, extra));
}

public static IEnumerable<Tuple<T1, T2, T3, T4>> ZipTuple<T1, T2, T3, T4>(
    this IEnumerable<T1> source1,
    IEnumerable<T2> source2,
    IEnumerable<T3> source3,
    IEnumerable<T4> source4)
{
    return source1
        .ZipTuple(source2, source3)
        .Zip(source4, (t1, extra) => Tuple.Create(t1.Item1, t1.Item2, t1.Item3, extra));
}

The direct version would look something like this:

public static IEnumerable<Tuple<T1, T2, T3, T4>> ZipTuple<T1, T2, T3, T4>(
    this IEnumerable<T1> source1,
    IEnumerable<T2> source2,
    IEnumerable<T3> source3,
    IEnumerable<T4> source4)
{
    // TODO: Extract a separate public method from the implementation
    // method and perform eager validation for nullity
    using (var iterator1 = source1.GetEnumerator())
    using (var iterator2 = source2.GetEnumerator())
    using (var iterator3 = source3.GetEnumerator())
    using (var iterator4 = source4.GetEnumerator())
    {
        while (iterator1.MoveNext() && iterator2.MoveNext() &&
               iterator3.MoveNext() && iterator4.MoveNext())
        {
            yield return Tuple.Create(
                iterator1.Current,
                iterator2.Current,
                iterator3.Current,
                iterator4.Current);
        }
    }
}

people

See more on this question at Stackoverflow