MSDN 是这样解释 Lookup 的:
A
Lookup<TKey, TElement>
类似于Dictionary<TKey, TValue>
. 不同之处在于 Dictionary<TKey, TValue>将键映射到单个值,而 Lookup<TKey, TElement>将键映射到值的集合。
我不觉得这个解释特别有用。查找用于什么?
MSDN 是这样解释 Lookup 的:
A
Lookup<TKey, TElement>
类似于Dictionary<TKey, TValue>
. 不同之处在于 Dictionary<TKey, TValue>将键映射到单个值,而 Lookup<TKey, TElement>将键映射到值的集合。
我不觉得这个解释特别有用。查找用于什么?
它是一个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>
类似于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
}
}
}
的一种用途Lookup
可能是反转 a Dictionary
。
假设您有一个电话簿实现为Dictionary
具有一堆(唯一)名称作为键,每个名称与一个电话号码相关联。但是两个不同名字的人可能共用同一个电话号码。这对于 a 来说不是问题Dictionary
,它不关心两个键对应相同的值。
现在,您需要一种查找给定电话号码所属人员的方法。您构建一个,从您的Lookup
中添加所有,但向后添加,以值作为键,键作为值。您现在可以查询电话号码,并获取电话号码所在的所有人的姓名列表。用相同的数据构建一个会丢弃数据(或失败,取决于你是怎么做的),因为做KeyValuePairs
Dictionary
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");
将在第二行引发异常,因为您不能Add
使用已经在Dictionary
.
[当然,您可能希望使用其他一些单一数据结构在两个方向上进行查找等。此示例意味着您必须Lookup
在Dictionary
每次后者更改时重新生成 。但对于某些数据,它可能是正确的解决方案。]
我以前没有成功使用过它,但这是我的尝试:
A 的Lookup<TKey, TElement>
行为非常类似于没有唯一约束的表上的(关系)数据库索引。在您将使用另一个相同的地方使用它。
我想你可以这样争论:想象你正在创建一个数据结构来保存电话簿的内容。您想按姓氏然后按名字键入。在这里使用字典会很危险,因为很多人可以有相同的名字。因此,字典将始终最多映射到单个值。
查找将映射到可能的多个值。
Lookup["Smith"]["John"] 将是一个大小为 10 亿的集合。