Pregunta

En Python hay una bonita función llamada zip que puede ser utilizado para iterar a través de dos listas al mismo tiempo:

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

El código anterior debe producir la siguiente:

1 a
2 b
3 c

Me pregunto si hay un método gusta disponibles en .Neta?Estoy pensando en escribir yo mismo, pero no hay ningún punto si ya está disponible.

¿Fue útil?

Solución

Actualización:Está construido en C# 4 como System.Linq.Enumerable.Zip Método

Aquí es un C# 3 versión:

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

Cayó el C# 2 versión como fue mostrando su edad.

Otros consejos

Que yo sepa no la hay.Yo escribí uno para mí (así como algunas otras extensiones útiles y ponerlos en un proyecto llamado NExtension en Codeplex.

Al parecer, el Paralelo extensiones para .NET tienen un Zip.

He aquí una versión simplificada de NExtension (pero por favor, échale un vistazo a la más útil métodos de extensión):

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

Uso:

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

Nope, no hay tal función en .NET.Usted tiene el rollo de su propio.Tenga en cuenta que C# no admite tuplas, por lo python-como la sintaxis de azúcar en la falta demasiado.

Puedes usar algo como esto:

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

También hay una en F#:

vamos con cremallera = Seq.zip firstEnumeration secondEnumation

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top