[英]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版本将是...。
与List.Contains
:
List<string> keysWithValue = dict .Where(kv => kv.Value.Contains(foo)) .Select(kv => kv.Key); .ToList();
或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.