2011-08-01 16 views
9

Cómo fusionar 2 diccionarios de IDictionary<Guid, MyObject> donde MyObject es una instancia de clase?Fusionando 2 diccionarios que tienen claves duplicadas con linq

IDictionary<Guid, MyObject> d1 = new Dictionary<Guid, MyObject>(); 
d1.Add(guid1, m1); 
d1.Add(guid2, m2); 
d1.Add(guid3, m3); 
IDictionary<Guid, MyObject> d2 = new Dictionary<Guid, MyObject>(); 
d2.Add(guid2, m2); 
d2.Add(guid3, m3); 
d2.Add(guid4, m4); 
IDictionary<Guid, MyObject> d3 = d1.Union(d2) ??? 

Que en d3 existen las siguientes entradas:

guid1,m1 
guid2,m2 
guid3,m3 
guid4,m4 
+0

duplicado de http://stackoverflow.com/questions/294138/merging-dictionaries-in-c – hatchet

+0

lo siento, no pude encontrar mi Solutiion no –

+0

posible duplicado de [Combinar dos diccionarios con linq] (http://stackoverflow.com/questions/4903784/combine-two-dictionaries-with-linq); duplicado más exacto que el otro –

Respuesta

9

d1.Concat (d2.Where (x => d1.Keys.Contains (x.Key))!);

+1

muchas gracias, ese es el enfoque correcto a través del proceso principal del conjunto concatenado –

+0

@Eric Esto parece una buena solución. Pero, si tengo una colección 'IEnuemrable >', ¿cómo puedo unir elementos? – barteloma

0

Usted podría intentar algo como

d1.Concat(d2).Distinct(kv => kv.Key).ToDictionary(kv => kv.Key, kv => kv.Value) 

El resultado de concat hace uso del hecho de que el diccionario es un IEnumerable<KeyvaluePair<Guid,MyObject>>

Como no tengo un compi Ler Acabo de comprobar que Distinct no puede aceptar solo una lambda seleccionando la propiedad que se va a comparar. Sin embargo, puede aceptar un EqualityComparer. Lo que a menudo tengo en los proyectos es un Comparer Genérico de Igualdad que permite pasar en lambdas que definen la operación de igualdad.

+0

sí, se necesita el comparador de igualdad –

0

Cuando no existen claves duplicadas, las siguientes obras para 2 (o más) los diccionarios:

var dictionaries = new [] { d1, d2 }; 
var result = dictionaries.SelectMany(dict => dict) 
        .ToDictionary(pair => pair.Key, pair => pair.Value); 
+1

bien, hay duplicados presentes –

5

d1.Union(d2).GroupBy (kvp => kvp.Key).ToDictionary(kvp => kvp.Key, kvp => kvp.First().Value); a hacer el truco.

IDictionary<Guid, MyObject> d1 = new Dictionary<Guid, MyObject>(); 
d1.Add(guid1, m1); 
d1.Add(guid2, m2); 
d1.Add(guid3, m3); 
IDictionary<Guid, MyObject> d2 = new Dictionary<Guid, MyObject>(); 
d2.Add(guid2, m2); 
d2.Add(guid3, m3); 
d2.Add(guid4, m4); 
IDictionary<Guid, MyObject> d3 = 
    d1.Union(d2).GroupBy (kvp => kvp.Key) 
     .ToDictionary (kvp => kvp.Key, kvp => kvp.First().Value); 
+0

gracias pero lo intenté y Union lleva a Exception con 'Un elemento con la misma clave ya ha sido agregado' –

+0

Lo arreglé. 'IDictionary d3 = d1.Union (d2) .GroupBy (kvp => kvp.Key) .ToDictionary (kvp => kvp.Key, kvp => kvp.First() .Value); ' –

+0

muchas gracias, eso funciona, ¿cómo esa línea evita las claves duplicadas? es más rápido que 'd1.Concat (d2.Where (x =>! D1.Keys.Contains (x.Key)))'? –

Cuestiones relacionadas