查找 < TKey,TElement > 的意义是什么?

MSDN 是这样解释查找的:

A < a < a < href = “ http://msdn.microsoft.com/en-us/library/bb460184% 28v = vs. 90% 29.aspx”rel = “ noReferrer”> Lookup<TKey, TElement> 类似于字典 < TKey, TValue > Dictionary < TKey,TValue > 将键映射到单个值,而 查找 < TKey,TElement > 将键映射到值的集合。

我不觉得这个解释特别有帮助。查找是用来做什么的?

103735 次浏览

它介于 IGrouping和字典之间。它允许您通过一个键将项分组在一起,但是然后通过该键以一种有效的方式访问它们(而不是仅仅迭代所有项,这是 GroupBy允许您做的)。

例如,您可以使用。NET 类型并根据命名空间构建查找... ... 然后很容易地找到特定命名空间中的所有类型:

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>的行为非常类似于没有唯一约束的表上的(关系)数据库索引。用在同样的地方,你会使用其他。

思考这个问题的一种方法是: 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()); // 1
Console.WriteLine("S's: {0}", namesByInitial['S'].Count()); // 2
Console.WriteLine("Z's: {0}", namesByInitial['Z'].Count()); // 0, does not throw
}
}
}

我想您可以这样说: 假设您正在创建一个数据结构来保存电话簿的内容。您希望通过 lastName 键入,然后通过 firstName 键入。在这里使用字典是很危险的,因为很多人可能有相同的名字。所以 Dictionary 最多只能映射到单个值。

查找将映射到可能的几个值。

查找[“史密斯”][“约翰”]将是一个大小为10亿的集合。

Lookup的一个用途可能是逆转 Dictionary

假设您有一个电话簿实现为 Dictionary,其中包含一组(唯一的)名称作为键,每个名称与一个电话号码相关联。但两个不同名字的人可能有相同的电话号码。这对于 Dictionary来说不是问题,因为 Dictionary不在乎两个键对应同一个值。

现在,您需要一种查找给定电话号码所属者的方法。构建一个 Lookup,从 Dictionary中添加所有的 KeyValuePairs,但是向后添加,值作为键,键作为值。您现在可以查询一个电话号码,并获得其电话号码为。使用相同的数据构建 Dictionary将丢弃数据(或者失败,这取决于您是如何做的) ,因为

dictionary["555-6593"] = "Dr. Emmett Brown";
dictionary["555-6593"] = "Marty McFly";

意味着第二个条目覆盖第一个-文件不再列出。

试着用稍微不同的方式写同样的数据:

dictionary.Add("555-6593", "Dr. Emmett Brown");
dictionary.Add("555-6593", "Marty McFly");

会在第二行抛出一个异常,因为你不能 Add一个键已经在 Dictionary

[当然,您可能希望使用其他一些单一数据结构来进行双向查找,等等。这个示例意味着,每次 Dictionary发生变化时,您都必须从 Dictionary重新生成 Lookup。但对于某些数据来说,这可能是正确的解决方案。]