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

Ale*_*kin 18 c# linq dictionary

我的代码中有以下结构Dictionary<TKeys, TValues> data;.我在两种数据类型上运行一些LINQ查询,并且经常需要在Keys和之间切换Values.获取给定值的键列表的最佳方法是什么,反之亦然?请通知,我通常有"IEnumerable的"和"的IEnumerable"我以前LINQ查询的结果,并希望有类似IEnumerable<TKeys> Dictionary.GetAllKeys(IEnumerable<IValues> vals)IEnumerable<TValues> Dictionary.GetAllValues(IEnumerable<IKeys> keys).

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

此致,亚历山大.

Bal*_*a R 34

 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);
Run Code Online (Sandbox Code Playgroud)

  • @Alaudo试试`var newdict = dictionary.Where(x => someKeys.Contains(x.Key)).ToDictionary(x => x.Key,x => x.Value);` (2认同)

Jon*_*eet 11

一个Dictionary<,>真的不是非常适合通过值算出键.您可以编写双向字典,就像我在这个答案中所做的那样,但它不一定是最好的方法.

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

var keysForValues = dictionary.Where(pair => values.Contains(pair.Value))
                              .Select(pair => pair.Key);
Run Code Online (Sandbox Code Playgroud)

请注意,这将是一个O(n)操作,即使您的"值"是一个HashSet或类似的(有效的包含检查).

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

public IEnumerable<T1> GetAllFirst<T1, T2>(IEnumerable<Tuple<T1, T2>> source,
                                           IEnumerable<T2> seconds)
{
    HashSet<T2> secondsSet = new HashSet<T2>(seconds);
    return source.Where(pair => secondsSet.Contains(pair.Item2));
}

public IEnumerable<T2> GetAllSecond<T1, T2>(IEnumerable<Tuple<T1, T2>> source,
                                            IEnumerable<T1> firsts)
{
    HashSet<T1> firstsSet = new HashSet<T1>(firsts);
    return source.Where(pair => firstsSet.Contains(pair.Item1));
}
Run Code Online (Sandbox Code Playgroud)