2010-07-15 46 views
8

我试图找到一个字典中不在另一个字典中的所有键。很显然,我可以使用嵌套循环来做到这一点,但我现在正在尝试学习LINQ,并且想知道是否可以使用它来完成此任务?使用LINQ来查找一个集合中所有不在另一个集合中的键?

这是我到目前为止有:

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

任何想法,我应该代替问号去(或者代替整个where子句的)?

+0

作为一个说明,也没有必要在你发布的代码“标签”之前指定类型。 – Kirk 2010-07-15 23:18:18

回答

11

你可以这样做:

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

Except()方法在本质上是相同的SQL操作minus - 返回从不包括在第二第一集合中的所有项目。由于字典暴露他们的密钥,你可以用这种方式计算他们的差异。

Except()运算符使用该类型的默认相等性,但也有一个重载允许您指定自己的IEqualityComparer以覆盖如何比较值的语义。在你的例子中,你可能不需要这个 - 但很高兴在那里知道它。

+4

请注意,'Except()'返回**不同**结果。虽然在这个例子中可能需要,但值得注意的是在其他实现中使用。 – Aren 2010-07-15 21:16:42

+0

@Aren B:确实如此,但对于Dictionary <>,它们的键已经保证是不同的。 – LBushkin 2010-07-15 21:17:45

+1

我知道,这就是为什么我说这个例子是期望的。但有人可能会偶然发现这个线程寻找* List Subtraction *并认为'Except()'可以解决他们的问题。因此,为什么我说这是值得注意的。 – Aren 2010-07-15 21:20:00

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; 

(但LBuskin的回答是更好)

0

如果你想使用查询语法我会做一些类似于如下:

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) 
{ 
} 
相关问题