Search code examples
c#linq

How to combine more than two generic lists in C# Zip?


I have three (it's possible to have more than 3-4 generic list, but in this example let 3) generic lists.

List<string> list1

List<string> list2

List<string> list3

all lists have same number of elements (same counts).

I used that for combining two lists with ZIP :

var result = list1.Zip(list2, (a, b) => new {
  test1 = f,
  test2 = b
}

I used that for foreach statement, to avoid foreach each List, like

foreach(var item in result){
Console.WriteLine(item.test1 + " " + item.test2);
}

How to use simmilary with Zip for three lists ?

Thanks

EDIT:

I want like:

List<string> list1 = new List<string>{"test", "otherTest"};

List<string> list2 = new List<string>{"item", "otherItem"};

List<string> list3 = new List<string>{"value", "otherValue"};

after ZIP (I don't know method), I want to result (in VS2010 debug mode)

[0] { a = {"test"},
      b = {"item"},
      c = {"value"}
    }   

[1] { a = {"otherTest"},
      b = {"otherItem"},
      c = {"otherValue"}
    }  

How to do that ?


Solution

  • The most obvious way for me would be to use Zip twice.

    For example,

    var results = l1.Zip(l2, (x, y) => x + y).Zip(l3, (x, y) => x + y);
    

    would combine (add) the elements of three List<int> objects.

    Update:

    You could define a new extension method that acts like a Zip with three IEnumerables, like so:

    public static class MyFunkyExtensions
    {
        public static IEnumerable<TResult> ZipThree<T1, T2, T3, TResult>(
            this IEnumerable<T1> source,
            IEnumerable<T2> second,
            IEnumerable<T3> third,
            Func<T1, T2, T3, TResult> func)
        {
            using (var e1 = source.GetEnumerator())
            using (var e2 = second.GetEnumerator())
            using (var e3 = third.GetEnumerator())
            {
                while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext())
                    yield return func(e1.Current, e2.Current, e3.Current);
            }
        }
    }
    

    The usage (in the same context as above) now becomes:

    var results = l1.ZipThree(l2, l3, (x, y, z) => x + y + z);
    

    Similarly, you three lists can now be combined with:

    var results = list1.ZipThree(list2, list3, (a, b, c) => new { a, b, c });