2010-07-15 16 views
8

Estoy tratando de localizar todas las claves en un diccionario que no están en otro diccionario. Obviamente, puedo hacer esto usando un ciclo anidado, pero estoy tratando de aprender LINQ en este momento y me preguntaba si podría usarlo para realizar esta tarea.¿Usar LINQ para encontrar todas las claves de una colección que no están en otra?

Esto es lo que tengo hasta ahora:

Dictionary<string, List<string>> DBtables = this.CollectTableListings(); 
var generic = from Dictionary<string,List<string>> tab 
       in DBtables 
       where !_tables.ContainsKey(???) 
       select tab; 

Alguna idea de lo que debe ir en el lugar de los signos de interrogación (o tal vez de toda la cláusula where)?

+0

Como nota, no hay necesidad de especificar el tipo antes "pestaña" en el código que envió. – Kirk

Respuesta

11

que puede hacer:

var resultKeys = DBTables.Keys.Except(_tables.Keys); 

El método Except() es esencialmente el mismo que los minus operaciones en SQL - devuelve todos los elementos de la primera colección con exclusión de los de la segunda. Dado que los diccionarios exponen sus claves, puede calcular su diferencia de esa manera.

El operador Except() usa la igualdad predeterminada para el tipo, pero también hay una sobrecarga que le permite especificar su propio IEqualityComparer para anular la semántica de cómo comparar valores. En su ejemplo, probablemente no lo necesite, pero es bueno saberlo allí.

+4

Tenga en cuenta que 'Except()' Devuelve ** resultados ** Distintivos. Si bien esto puede ser deseable en este ejemplo, vale la pena señalarlo para su uso en otras implementaciones. – Aren

+0

@Aren B: cierto, pero en el caso de un 'Diccionario <>', ya se garantiza que las claves serán distintas. – LBushkin

+1

Lo sé, es por eso que dije que este ejemplo es deseado. Pero alguien puede tropezar con este hilo buscando una * Substracción de lista * y pensar que 'Except()' puede resolver sus problemas. Por lo tanto, por qué dije que valía la pena señalarlo. – Aren

2
Dictionary<string, List<string>> dictOne = ... 
Dictionary<string, List<string>> dictTwo = ... 

var missingKeys = dictOne.Keys.Where(x => !dictTwo.ContainsKey(x)); 
1
Dictionary<string, List<string>> dictionary = this.CollectTableListings(); 
Dictionary<string, List<string>> otherDictionary = getOtherTable(); 

var keys = from key in dictionary.Keys 
      where !otherDictionary.Keys.Contains(key) 
      select key; 

(Pero la respuesta de LBuskin es mucho mejor)

0

echar un vistazo al método Except extensión. HTH.

0

Si desea utilizar la sintaxis de consulta me gustaría hacer algo parecido a continuación:

var keys = from d1 in dictionary1 
      select d1.Key; 
var items = from d2 in dictionary2 
      where d2.Key in keys 
      select d2; 
foreach(var item in items) 
{ 
} 
Cuestiones relacionadas