Frage

In Python gibt es eine wirklich nette Funktion namens zip, die verwendet werden können, durch zwei Listen gleichzeitig iterieren:

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

Der obige Code sollte die folgenden produzieren:

1 a
2 b
3 c

Ich frage mich, wenn es ein Verfahren, wie es in .net? Ich denke darüber nach, es selbst zu schreiben, aber es hat keinen Sinn, wenn es bereits vorhanden ist.

War es hilfreich?

Lösung

Update: Es ist eingebaut in C # 4: System.Linq.Enumerable.Zip Methode

Hier ist eine 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 die C # 2-Version, wie es sein Alter zeigte.

Andere Tipps

Soweit ich weiß, gibt es nicht. Ich schrieb einen für mich (wie auch einige andere nützliche Erweiterungen und legte sie in einem Projekt namens NExtension auf Codeplex.

Anscheinend ist die Parallel-Erweiterungen für .NET, um eine Zip-Funktion haben.

Hier ist eine vereinfachte Version von NExtension (aber überprüfen Sie es bitte für weitere nützliche Erweiterung Methoden aus):

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);
        }
}

Verbrauch:

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);

Nein, es gibt keine solche Funktion in .NET. Sie haben eine eigene ausrollen. Beachten Sie, dass C # nicht Tupel unterstützen, so Python-ähnliche Syntax Zucker fehlt auch.

Sie können so etwas wie folgt verwenden:

class Pair<T1, T2>
{
    public T1 First { get; set;}
    public T2 Second { get; set;}
}

static IEnumerable<Pair<T1, T2>> Zip<T1, T2>(IEnumerable<T1> first, IEnumerable<T2> second)
{
    if (first.Count() != second.Count())
        throw new ArgumentException("Blah blah");

    using (IEnumerator<T1> e1 = first.GetEnumerator())
    using (IEnumerator<T2> e2 = second.GetEnumerator())
    {
        while (e1.MoveNext() && e2.MoveNext())
        {
            yield return new Pair<T1, T2>() {First = e1.Current, Second = e2.Current};
        }
    }
}

...

var ints = new int[] {1, 2, 3};
var strings = new string[] {"A", "B", "C"};

foreach (var pair in Zip(ints, strings))
{
    Console.WriteLine(pair.First + ":" + pair.Second);
}

Es gibt auch eine in F #:

lassen Reißverschluss = Seq.zip firstEnumeration secondEnumation

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top