Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a zip-like method in .Net?

In Python there is a really neat function called zip which can be used to iterate through two lists at the same time:

list1 = [1, 2, 3]
list2 = ["a", "b", "c"]
for v1, v2 in zip(list1, list2):
    print v1 + " " + v2

The above code should produce the following:

1 a
2 b
3 c

I wonder if there is a method like it available in .Net? I'm thinking about writing it myself, but there is no point if it's already available.

like image 1000
Jonas Avatar asked Sep 19 '08 11:09

Jonas


2 Answers

Update: It is built-in in C# 4 as System.Linq.Enumerable.Zip Method

Here is a C# 3 version:

IEnumerable<TResult> Zip<TResult,T1,T2>
    (IEnumerable<T1> a,
     IEnumerable<T2> b,
     Func<T1,T2,TResult> combine)
{
    using (var f = a.GetEnumerator())
    using (var s = b.GetEnumerator())
    {
        while (f.MoveNext() && s.MoveNext())
            yield return combine(f.Current, s.Current);
    }
}

Dropped the C# 2 version as it was showing its age.

like image 81
12 revs, 3 users 93% Avatar answered Oct 24 '22 13:10

12 revs, 3 users 93%


As far as I know there is not. I wrote one for myself (as well as a few other useful extensions and put them in a project called NExtension on Codeplex.

Apparently the Parallel extensions for .NET have a Zip function.

Here's a simplified version from NExtension (but please check it out for more useful extension methods):

public static IEnumerable<TResult> Zip<T1, T2, TResult>(this IEnumerable<T1> source1, IEnumerable<T2> source2, Func<T1, T2, TResult> combine)
{
    using (IEnumerator<T1> data1 = source1.GetEnumerator())
    using (IEnumerator<T2> data2 = source2.GetEnumerator())
        while (data1.MoveNext() && data2.MoveNext())
        {
            yield return combine(data1.Current, data2.Current);
        }
}

Usage:

int[] list1 = new int[] {1, 2, 3};
string[] list2 = new string[] {"a", "b", "c"};

foreach (var result in list1.Zip(list2, (i, s) => i.ToString() + " " + s))
    Console.WriteLine(result);
like image 35
Cameron MacFarland Avatar answered Oct 24 '22 12:10

Cameron MacFarland