繁体   English   中英

当值是C#中的对象列表时,如何查找字典的键?

[英]How to find the key of a dictionary when the value is a list of objects in C#?

当我有一个对象列表作为值时,我想找到相应的键。 假设我有一本字典,

 Dictionary<string, List<object>> dict = new Dictionary<string, List<object>>(); 

我知道我可以做些类似的事情,

foreach (var item in dict)
{
    foreach (var subItem in item.Value)
    {
        if (subItem.Equals(foo))
        {
              Console.WriteLine(item.Key);
        }
     }
}

但这需要花费大量时间,我拥有大量的数据集。 有更快的解决方案吗?

我知道使用LINQ查找给定值的键的正常方法是这样的:

var keysWithMatchingValues = dict.Where(p => p.Value == myObject).Select(p => p.Key);

我正在寻找适合自己情况的类似解决方案。

LINQ在大多数情况下并不是性能更高,但是使用LINQ编写正确且可读的代码通常更容易。 如果没有可能的重复值,我将使用HashSet<T>而不是列表。 如果您知道它是什么类型,我将使用该类型而不是对象。

您的代码的LINQ版本将是...。

  1. List.Contains

     List<string> keysWithValue = dict .Where(kv => kv.Value.Contains(foo)) .Select(kv => kv.Key); .ToList(); 
  2. Enumerable.Any

     List<string> keysWithValue = dict .Where(kv => kv.Value.Any(v => foo.Equals(v))) .Select(kv => kv.Key); .ToList(); 

但是如前所述,这不会更有效。 一种提高性能的方法是使用Lookup<TKey, TValue> 如果字典没有变化,则只需创建一次即可:

var valueToKeyLookup = dict  // make it an instance field, so that you don't have to create it always
    .SelectMany(kv => kv.Value
        .Distinct()
        .Select(v => new {Key = kv.Key, Value = v})
    )
    .ToLookup(x => x.Value, x => x.Key);

现在剩下的代码非常简洁高效:

List<string> allKeysWithFoo = valueToKeyLookup[foo].ToList();

请注意,即使没有列表包含该值,这也将起作用,那么结果将是一个空列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM