我需要确定List
中包含的任何Dictionary
是否包含指定的值。我是LINQ的新手,以下是实现这一目标的正确方法吗?
Dictionary lotsOfStuff = new Dictionary<string, List<string>>();
string searchString;
// populate lotsOfStuff and searchString...
// detemine if any of the values of lotsOfStuff contain searchString
bool existsInDictionary = lotsOfStuff.Values.Any(values => values.Contains(searchString));
如果以上方法有效,有没有办法让它更正确或更优/更简洁?
答案 0 :(得分:3)
此代码有效并且尽可能高效。因为您正在搜索值,所以没有索引/哈希来指导搜索。因此,您必须搜索所有对象以确定值是否存在。
答案 1 :(得分:3)
您的代码可以正常运行,但有两件事情会立即浮现在脑海中。首先,如果字典很大或值列表很大,它会很慢。我想到的第二件事是你试图进行这种搜索,这告诉我你已经把字典倒在了一起。如果你有一本字典:
"Frob" --> "Foo", "Bar", "Baz"
"Blob" --> "Baz", "ABC"
你问的问题是“在任何价值清单中都是ABC吗?”然后你向后建了字典。您要构建的词典是
"Foo" --> "Frob"
"Bar" --> "Frob"
"Baz" --> "Frob", "Blob"
"ABC" --> "Blob"
你应该问的问题是“ABC是字典的关键吗?”你为什么要建立字典向后?
答案 2 :(得分:1)
该代码存在潜在问题。如果其中一个列表为null
(即使该值存在于另一个列表中),您可能会获得NullReferenceException
。要修复,请尝试:
bool existsInDictionary = lotsOfStuff.Values
.Any(values => values != null && values.Contains(searchString));
答案 3 :(得分:0)
假设您想要区分大小写的匹配,您的代码将起作用,并且是最好的方法。
如果您想要不区分大小写的匹配,请传递StringComparer
,如下所示:
lotsOfStuff.Values.Any(values => values.Contains(searchString, StringComparer.OrdinalIgnoreCase));
顺便说一下,如果你想获得所有的值,你可以写
var allValues = lotsOfStuff.Values.SelectMany(v => v);
答案 4 :(得分:0)
你的linq很好,我就是这样做的
bool existsInDictionary = lotsOfStuff
.SelectMany(kvp => kvp.Value)
.Any(valString => valString == searchString);
ILookup<string, string> reverseLookup =
(
from kvp in lotsOfStuff
from valString in kvp.Value
select new {key = valString, value = kvp.Key}
).ToLookup(x => x.key, x => x.value);
bool existsInDictionary = reverseLookup[searchString].Any();