2011-11-29 22 views
14

Ho due IEnumerable<double> s, che voglio costruire un IEnumerable di Tuple<int, double, double> da. Item1 dello Tuple dovrebbe essere l'indice dell'articolo, Item2 il valore in posizione index-th nella prima raccolta e il valore Item3 nella posizione index-th nella seconda raccolta. È qualcosa che può essere fatto facilmente in Linq?Posso creare tuple da IEnumerables usando Linq?

E.g.

var first = new List<double>() { 10.0, 20.0, 30.0 }; 
var second = new List<double>() { 1.0, 2.0, 3.0 }; 
var result = TupleBuild(first, second); 
// result = {(0, 10.0, 1.0), (1, 20.0, 2.0), (2, 30.0, 3.0)} 

dove:

IEnumerable<Tuple<int, double, double>> TupleBuild(IEnumerable<double> first, IEnumerable<double> second) 
{ 
    // does some funky Linq 
} 

mi rendo conto che potrei scrivere del codice longhand per questo, ma preferisco non reinventare la ruota se Linq ha questo coperto.

risposta

22

ne dite con il Zip operatore e il Select overload che fornisce l'indice dell'elemento:

return first.Zip(second, Tuple.Create) 
      .Select((twoTuple, index) 
         => Tuple.Create(index, twoTuple.Item1, twoTuple.Item2)); 

A proposito, si potrebbe anche poi fare il metodo generico:

IEnumerable<Tuple<int, TFirst, TSecond>> TupleBuild<TFirst, TSecond> 
(IEnumerable<TFirst> first, IEnumerable<TSecond> second) { ... } 
+0

Eccellente , Grazie! Vorrei poterti dare un voto in più per avermi introdotto all'estensione Zip :) –

+0

E vorrei poter invocare due volte per Zip e il Seleziona sovraccarico. – drdwilcox