2012-09-28 9 views
6

duplicados posible:
Create Items from 3 collections using LinqCómo utilizar Zip en tres IEnumerables

he realizado un zippage de dos secuencias de la siguiente manera.

IEnumerable<Wazoo> zipped = arr1.Zip(arr2, (outer, inner) => 
    new Wazoo{P1 = outer, P2 = inner}); 

Ahora, me acabo de dar cuenta de que usaré tres secuencias, no dos. Así que traté de rediseñar el código a algo como esto:

IEnumerable<Wazoo> zipped = arr1.Zip(arr2, arr3, (e1, e2, e3) => 
    new Wazoo{P1 = e1, P2 = e2, P3 = e3}); 

Por supuesto, no funcionó. ¿Hay alguna manera de implementar Zip para incorporar lo que estoy buscando? ¿Hay algún otro método para tal uso? ¿Tendré que comprimir dos de las secuencias y luego comprimirlas con la tercera descomprimiéndolas en el proceso?

En este punto estoy a punto de crear un simple for-loop y yield return la estructura solicitada. ¿Debería? Estoy en .Net 4.

+0

similar: http://stackoverflow.com/questions/5284315/create-items-from-3-collections-using-linq – AakashM

+0

@AakashM: Creo que eso no es sólo similares, es un duplicado. –

+0

@Ben, así que veo, este es acerca de las matrices que tienen un indexador rápido como la 'Lista's en el enlace, por lo que sí se aplica la misma solución. Aún no se ha planteado la interesante pregunta sobre qué hacer con un 'IEnumerable <>' arbitrario ... – AakashM

Respuesta

10

Puede usar dos llamadas al Zip existente (sería un poco desordenado, pero funcionaría) o simplemente podría hacer su propio Zip que tome 3 secuencias.

public static IEnumerable<TResult> Zip<TFirst, TSecond, TThird, TResult> 
    (this IEnumerable<TFirst> source, IEnumerable<TSecond> second 
    , IEnumerable<TThird> third 
    , Func<TFirst, TSecond, TThird, TResult> selector) 
{ 
    using(IEnumerator<TFirst> iterator1 = source.GetEnumerator()) 
    using(IEnumerator<TSecond> iterator2 = second.GetEnumerator()) 
    using (IEnumerator<TThird> iterator3 = third.GetEnumerator()) 
    { 
     while (iterator1.MoveNext() && iterator2.MoveNext() 
      && iterator3.MoveNext()) 
     { 
      yield return selector(iterator1.Current, iterator2.Current, 
       iterator3.Current); 
     } 
    } 
} 
+1

Buena respuesta, excepto que cambiaría el nombre del método a 'PerformZippage' –

Cuestiones relacionadas