LINQ:从字典中获取给定值列表的密钥,反之亦然

本文关键字:列表 密钥 反之亦然 字典 获取 LINQ | 更新日期: 2023-09-27 18:00:27

我的代码Dictionary<TKeys, TValues> data;中有以下结构。我对这两种数据类型都运行了一些LINQ查询,并且经常需要在KeysValues之间切换。获取给定值的键列表的最佳方法是什么,反之亦然?请注意,由于我以前的LINQ查询,我通常有"IEnumerable"answers"IEnumarable",并且希望有类似IEnumerable<TKeys> Dictionary.GetAllKeys(IEnumerable<IValues> vals)IEnumerable<TValues> Dictionary.GetAllValues(IEnumerable<IKeys> keys)的内容。

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

谨致问候,亚历山大。

LINQ:从字典中获取给定值列表的密钥,反之亦然

 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<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));
}

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

例如:

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