2009-04-03 9 views
44

Ho due dizionari di tipo <string,object> in C#. Come posso copiare tutti i contenuti di un oggetto Dizionario all'altro senza applicare un ciclo?Come combinare due dizionari senza eseguire il ciclo?

+0

Il nome del tipo nella tua domanda sembra essere diventato AWOL. – dommer

+0

se stai cercando un'unione dovresti fare riferimento a: http://stackoverflow.com/questions/294138/merging-dictionaries-in-c – annakata

risposta

5
var result = dictionaries.SelectMany(dict => dict) 
      .ToDictionary(pair => pair.Key, pair => pair.Value); 
38

È possibile utilizzare Concat:

Dictionary<string, object> d1 = new Dictionary<string, object>(); 
d1.Add("a", new object()); 
d1.Add("b", new object()); 
Dictionary<string, object> d2 = new Dictionary<string, object>(); 
d2.Add("c", new object()); 
d2.Add("d", new object()); 

Dictionary<string, object> d3 = d1.Concat(d2).ToDictionary(e => e.Key, e => e.Value); 

foreach (var item in d3) 
{ 
    Console.WriteLine(item.Key); 
} 
+1

Ciò restituirà un oggetto IEnumerable >, è necessario chiamare ToDictionary per ottenere un dizionario. –

+0

È vero. Grazie per la segnalazione. Modificherà. –

9

Prima di tutto, non è possibile senza loop. Se quel loop è fatto in un metodo (estensione) è irrilevante, richiede comunque un ciclo.

In realtà consiglierò di farlo manualmente. Tutte le altre risposte fornite richiedono l'utilizzo di due metodi di estensione (Concat - ToDictionary e SelectMany - ToDictionary) e quindi ripetuti due volte. Se si sta facendo questo per ottimizzare il codice, sarà più veloce di fare un ciclo su dizionario B e aggiungere il suo contenuto a dizionario A.

Edit: Dopo ulteriori indagini, si verificherebbero solo l'operazione Concat durante la ToDictionary chiama, ma penso ancora che un metodo di estensione personalizzato sarebbe più efficiente.

Se si desidera ridurre la dimensione del codice, poi basta fare un metodo di estensione:

public static class DictionaryExtensions 
{ 
    public static IDictionary<TKey,TVal> Merge<TKey,TVal>(this IDictionary<TKey,TVal> dictA, IDictionary<TKey,TVal> dictB) 
    { 
     IDictionary<TKey,TVal> output = new Dictionary<TKey,TVal>(dictA); 

     foreach (KeyValuePair<TKey,TVal> pair in dictB) 
     { 
      // TODO: Check for collisions? 
      output.Add(pair.Key, Pair.Value); 
     } 

     return output; 
    } 
} 

Quindi è possibile utilizzare importando ('usando') lo spazio dei nomi DictionaryExtensions e la scrittura:

IDictionary<string,objet> output = dictA.Merge(dictB); 

Ho fatto in modo che il metodo agisse come se gli oggetti fossero immutabili, ma potreste facilmente modificarlo per non restituire un nuovo dizionario e semplicemente unirmi a dictA.

87
var d3 = d1.Concat(d2).ToDictionary(x => x.Key, x => x.Value); 
+0

Questo è esattamente lo stesso della risposta di Bruno. –

+0

Simplefied ma la stessa risposta sì, non una ragione di downvote – RvdK

+0

Scusate ma ho postato prima bruno ha aggiornato la sua risposta per includere la chiamata ToDictionary - in precedenza il codice restituiva un IEnumerable