查找<TKey,TElement>的要点是什么?
MSDN解释这样的查找:
Lookup<TKey, TElement>
类似于Dictionary<TKey, TValue>
。 区别在于Dictionary <TKey,TValue>将键映射到单个值,而Lookup <TKey,TElement>将键映射到值集合。
我不觉得这个解释特别有用。 什么是查找使用?
这是IGrouping
和字典之间的交叉。 它允许你通过一个键把项目组合在一起,然后通过这个键以高效的方式访问它们(而不是仅仅遍历它们,这是GroupBy
允许你做的)。
例如,你可以使用.NETtypes的负载,并通过命名空间构build查找…然后非常容易地获取特定命名空间中的所有types:
using System; using System.Collections.Generic; using System.Linq; using System.Xml; public class Test { static void Main() { // Just types covering some different assemblies Type[] sampleTypes = new[] { typeof(List<>), typeof(string), typeof(Enumerable), typeof(XmlReader) }; // All the types in those assemblies IEnumerable<Type> allTypes = sampleTypes.Select(t => t.Assembly) .SelectMany(a => a.GetTypes()); // Grouped by namespace, but indexable ILookup<string, Type> lookup = allTypes.ToLookup(t => t.Namespace); foreach (Type type in lookup["System"]) { Console.WriteLine("{0}: {1}", type.FullName, type.Assembly.GetName().Name); } } }
(我通常使用var
的大部分这些声明,在正常的代码。)
一种想法是这样的: Lookup<TKey, TElement>
类似于Dictionary<TKey, Collection<TElement>>
。 基本上可以通过同一个键返回零个或多个元素的列表。
namespace LookupSample { using System; using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { List<string> names = new List<string>(); names.Add("Smith"); names.Add("Stevenson"); names.Add("Jones"); ILookup<char, string> namesByInitial = names.ToLookup((n) => n[0]); // count the names Console.WriteLine("J's: {0}", namesByInitial['J'].Count()); Console.WriteLine("S's: {0}", namesByInitial['S'].Count()); Console.WriteLine("Z's: {0}", namesByInitial['Z'].Count()); } } }
Lookup
一个用途可能是翻转Dictionary
。
假设你有一个电话簿实现为一个Dictionary
,有一堆(唯一)名称作为键,每个名字都与一个电话号码相关联。 但是有两个名字不同的人可能会分享相同的电话号码。 这不是一个Dictionary
的问题,它不关心两个键对应于相同的值。
现在,您需要查找给定电话号码所属的人的方式。 你build立一个Lookup
,从你的Dictionary
join所有的KeyValuePairs
,但是向后的值是键值和键值。 你现在可以查询一个电话号码,并获得所有电话号码是谁的人名单。 build立一个相同的数据Dictionary
将放弃数据(或失败,取决于你如何做),因为这样做
dictionary["555-6593"] = "Dr. Emmett Brown"; dictionary["555-6593"] = "Marty McFly";
意味着第二项将覆盖第一项 – Doc不再列出。
试图用稍微不同的方式编写相同的数据:
dictionary.Add("555-6593", "Dr. Emmett Brown"); dictionary.Add("555-6593", "Marty McFly");
会在第二行抛出一个exception,因为你不能Add
已经在Dictionary
的键。
[当然,您可能希望使用其他单一数据结构在两个方向上执行查找等。此示例意味着每当后者发生更改时,都必须从“ Dictionary
重新生成“ Lookup
”。 但对于一些数据来说,这可能是正确的解决scheme。]
我以前没有成功地使用过,但是这是我的发现:
Lookup<TKey, TElement>
行为几乎就像一个没有唯一约束的(关系)数据库索引。 使用它在相同的地方,你会使用其他。
我想你可以这样争论:假设你正在创build一个数据结构来保存电话簿的内容。 你想按lastName键,然后按firstName键。 在这里使用字典会很危险,因为很多人可以拥有相同的名字。 所以一个字典最多只能映射一个值。
查找将映射到可能的几个值。
查询[“史密斯”] [“约翰”]将是一个十亿大小的集合。