LINQ:从Dictionary获取给定值列表的键,反之亦然

我的代码Dictionary data;有以下结构Dictionary data; 。 我在两种数据类型上运行一些LINQ查询,并且经常需要在KeysValues之间切换。 获取给定值的键列表的最佳方法是什么,反之亦然? 请注意,由于我之前的LINQ查询,我通常有’IEnumerable’和’IEnumerable’,并希望有像IEnumerable Dictionary.GetAllKeys(IEnumerable vals)IEnumerable Dictionary.GetAllValues(IEnumerable keys)

也许我需要其他数据容器来完成这项任务?

此致,亚历山大。

  var values = dictionary.Where(x => someKeys.Contains(x.Key)).Select(x => x.Value); var keys = dictionary.Where(x => someValues.Contains(x.Value)).Select(x => x.Key); 

Dictionary<,>真的不适合按值查找键。 你可以写一个双向字典,正如我在这个答案中所做的那样 ,但它不一定是最好的方法。

当然,您可以使用字典作为键/值对的序列,因此您可以:

 var keysForValues = dictionary.Where(pair => values.Contains(pair.Value)) .Select(pair => pair.Key); 

请注意,这将是一个O(n)操作,即使您的“值”是HashSet或类似的东西(使用有效的包含检查)。

编辑:如果你真的不需要键/值关系 – 如果它更像是它们只是成对 – 那么使用List>会产生一定的意义。 查询最终是相同的,基本上:

 public IEnumerable GetAllFirst(IEnumerable> source, IEnumerable seconds) { HashSet secondsSet = new HashSet(seconds); return source.Where(pair => secondsSet.Contains(pair.Item2)); } public IEnumerable GetAllSecond(IEnumerable> source, IEnumerable firsts) { HashSet firstsSet = new HashSet(firsts); return source.Where(pair => firstsSet.Contains(pair.Item1)); } 

最好的方法是对键值对的集合执行linq查询,然后使用Select投影选择查询末尾的Keys或Values。 这样就无需在查询结束时执行查找。

例如:

  Dictionary data = new Dictionary(); // select all values for keys that contain the letter 'A' var values = data.Where(pair => pair.Key.Contains("A")) .Select(pair => pair.Value);