2011-08-18 12 views
9

Ho due elenchi di oggetti. Elenco A e Elenco B. Devo creare la lista C che combina l'elenco A e l'elenco B in coppie. Ad esempio:Come creare un singolo elenco di coppie di oggetti da due elenchi in C#?

List A 
object a1 
object a2 
object a3 

List B 
object b1 
object b2 
object b3 

List C (creates pairs) 
object c1 (object a1, object b1) 
object c2 (object a2, object b2) 
object c3 (object a3, object b3) 
+0

vedono questo http://stackoverflow.com/questions/166089/what-is- c-analog-of-c-stdpair –

risposta

4

Questo lo farebbe:

public static IEnumerable<Tuple<T, U>> CombineWith<T, U>(this IEnumerable<T> first, IEnumerable<U> second) 
{ 
    using (var firstEnumerator = first.GetEnumerator()) 
    using (var secondEnumerator = second.GetEnumerator()) 
    { 
     bool hasFirst = true; 
     bool hasSecond = true; 

     while (
      // Only call MoveNext if it didn't fail last time. 
      (hasFirst && (hasFirst = firstEnumerator.MoveNext())) 
      | // WARNING: Do NOT change to ||. 
      (hasSecond && (hasSecond = secondEnumerator.MoveNext())) 
      ) 
     { 
      yield return Tuple.Create(
        hasFirst ? firstEnumerator.Current : default(T), 
        hasSecond ? secondEnumerator.Current : default(U) 
       ); 
     } 
    } 
} 

Edit: Io preferisco di gran lunga Paul's risposta.

+1

Vorrei usare la soluzione di Paul se potessi usare il framework 4.0 ma questo funziona su 3.5 quindi grazie! – Earl

+0

@Earl Come funziona su 3.5? 'Tuple' è [disponibile solo dalla 4.0] (http://msdn.microsoft.com/es-es/library/system.tuple%28v=vs.100%29.aspx). –

26

È possibile utilizzare il metodo Enumerable.Zip() in System.Linq.

IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB, (a, b) => Tuple.Create(a, b)); 

Esempio utilizza questo risultante enumerable:

foreach (Tuple<A, B> pair in pairs) 
{ 
    A a = pair.Item1; 
    B b = pair.Item2; 
} 

peccato non c'è un sovraccarico che automatizza il tupleation NET. Tale estensione sarebbe simile a questa:

public static IEnumerable<Tuple<TFirst, TSecond>> Zip<TFirst, TSecond>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second) 
{ 
    return first.Zip(second, Tuple.Create); 
} 

Il che significa che si può quindi scrivere codice simile:

IEnumerable<Tuple<A, B>> pairs = listA.Zip(listB); 

Nota: Un'altra opzione potrebbe essere quella di creare tipi anonimi, invece di Tuple ma il rovescio della medaglia a questo approccio è che non sarebbe possibile (utilmente) passare l'IEnumerable risultante dal metodo che è stato creato, a causa del tipo che non ha un nome.

+0

fare riferimento a questo collegamento msdn per maggiori dettagli: http://msdn.microsoft.com/en-us/library/dd267698.aspx – Tarang

+1

Molto meglio della mia soluzione :). –

+0

Grazie, ottimo suggerimento - tuttavia, questo sembra disponibile solo in Framework 4.0. Sfortunatamente sono limitato a 3.5 su questo progetto. – Earl

1

Quando dici "Coppie" intendi coppie chiave/valore?

Se è così, si desidera utilizzare Dictionary<object, object>

3

Qualcosa di simile a questo:

var listA = new object[] { "1", "2", "3" }; 
var listB = new object[] { "a", "b", "c" }; 
var listC = Enumerable.Zip(listA,listB, (x,y)=>new {x,y}); 

foreach (var item in listC) 
{ 
    Console.WriteLine("{0},{1}", item.x,item.y); 
} 

uscita: 1, un 2, b 3, c

Problemi correlati