C# 测试字典中是否包含值<;TKey,List<;TValue>&燃气轮机;

C# 测试字典中是否包含值<;TKey,List<;TValue>&燃气轮机;,c#,linq,.net-3.5,linq-to-entities,C#,Linq,.net 3.5,Linq To Entities,我需要确定字典中包含的列表是否包含指定的值。我是LINQ的新手,那么以下是实现这一目标的正确方法吗 Dictionary lotsOfStuff = new Dictionary<string, List<string>>(); string searchString; // populate lotsOfStuff and searchString... // detemine if any of the values of lotsOfStuff contain

我需要确定
字典
中包含的
列表
是否包含指定的值。我是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));
Dictionary lotsOfStuff=newdictionary();
字符串搜索字符串;
//填充lotsOfStuff和searchString。。。
//确定LotusStuff的任何值是否包含searchString
bool existsInDictionary=lotsofsuff.Values.Any(Values=>Values.Contains(searchString));

如果上述方法可行,是否有任何方法使其更正确或更优化/简洁?

此代码可以正常工作,并尽可能提高效率。因为您正在搜索值,所以没有索引/哈希来指导搜索。因此,必须搜索所有对象以确定该值是否存在

假设您需要区分大小写的匹配,那么您的代码可以工作,并且是最好的方式

如果需要不区分大小写的匹配,请传递一个
StringComparer
,如下所示:

lotsOfStuff.Values.Any(values => values.Contains(searchString, StringComparer.OrdinalIgnoreCase));
顺便说一下,如果你想得到所有的值,你可以写

var allValues = lotsOfStuff.Values.SelectMany(v => v);

这段代码有一个潜在的问题。如果其中一个列表为
null
(即使该值存在于另一个列表中),您可能会得到
NullReferenceException
。要修复此问题,请尝试:

bool existsInDictionary = lotsOfStuff.Values
             .Any(values => values != null && values.Contains(searchString));

您的代码将正常工作,但有两件事会立即浮现在脑海中。第一个问题是,如果字典很大或值列表很大,速度会很慢。我想到的第二件事是,你正在尝试进行这种搜索,这告诉我你已经把字典放反了。如果你有字典:

"Frob" --> "Foo", "Bar", "Baz"
"Blob" --> "Baz", "ABC"
你要问的问题是“ABC在任何值列表中吗?”然后你已经反向构建了字典。你要建立的字典是

"Foo" --> "Frob"
"Bar" --> "Frob"
"Baz" --> "Frob", "Blob"
"ABC" --> "Blob"

你应该问的问题是“ABC是字典的关键吗?”你为什么要反向构建字典?

你的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();
i查看反向查看=
(
来自lotsOfStuff中的kvp
从以kvp.值表示的valString
选择新建{key=valString,value=kvp.key}
).ToLookup(x=>x.key,x=>x.value);
bool existsInDictionary=reverseLookup[searchString].Any();

@Robert,在这种情况下不是因为用户正在搜索值中的值,而不是值本身。如果您不希望遍历整个字典来查找,那么应该使用什么结构?值被索引的字典的一些变体?@Robert,任何提供非线性搜索功能的结构。例如,平衡二叉树、哈希表、排序列表等……我正在目录树中搜索存储过程名称。在这种情况下,
字典
的键是文件的路径名,而值是在该文件中找到的所有进程名的
列表
(因为单个文件中可以包含不同数量的存储进程)。在以后的阶段,我需要生成一个包含此信息的报告,但在此之前,我必须确定
字典中是否存在具有特定名称的过程。我使用的方法似乎是实现所需的最简单的方法,但如果你有任何其他建议,我很高兴听到!然后我将构建两个字典,一个映射目录-->过程名称列表,一个映射过程名称-->目录列表。这会占用两倍的内存,但搜索速度会快得多。