C# Lookup<TKey, TElement> 有什么意义?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1403493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 16:08:04  来源:igfitidea点击:

What is the point of Lookup<TKey, TElement>?

c#.netlinqlookup

提问by dan-gph

The MSDN explains Lookup like this:

MSDN 对 Lookup 的解释如下:

A Lookup<TKey, TElement>resembles a Dictionary<TKey, TValue>. The difference is that a Dictionary<TKey, TValue>maps keys to single values, whereas a Lookup<TKey, TElement>maps keys to collections of values.

ALookup<TKey, TElement>类似于Dictionary<TKey, TValue>。区别在于 Dictionary<TKey, TValue>将键映射到单个值,而 Lookup<TKey, TElement>将键映射到值的集合。

I don't find that explanation particularly helpful. What is Lookup used for?

我不认为这种解释特别有帮助。查找有什么用?

采纳答案by Jon Skeet

It's a cross between an IGroupingand a dictionary. It lets you group items together by a key, but then access them via that key in an efficient manner (rather than just iterating over them all, which is what GroupBylets you do).

IGrouping是字典和字典之间的交叉。它让您可以通过一个键将项目组合在一起,然后通过该键以一种有效的方式访问它们(而不是仅仅遍历它们,这是GroupBy您可以执行的操作)。

For example, you could take a load of .NET types and build a lookup by namespace... then get to all the types in a particular namespace very easily:

例如,您可以加载 .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);
        }
    }
}

(I'd normally use varfor most of these declarations, in normal code.)

(我通常var在普通代码中用于大多数这些声明。)

回答by Daren Thomas

I haven't successfully used it before, but here is my go:

我以前没有成功使用过它,但这是我的做法:

A Lookup<TKey, TElement>would behave pretty much like a (relational) database index on a table without a unique constraint. Use it in the same places you would use the other.

A 的Lookup<TKey, TElement>行为非常类似于表上的(关系)数据库索引,没有唯一约束。在与使用另一个相同的地方使用它。

回答by bobbymcr

One way to think about it is this: Lookup<TKey, TElement>is similar to Dictionary<TKey, Collection<TElement>>. Basically a list of zero or more elements can be returned via the same key.

一种思考方式是: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
        }
    }
}

回答by David Andres

I guess you could argue it this way: imagine you're creating a data structure to hold the contents of a phone book. You want to key by lastName and then by firstName. Using a dictionary here would be dangerous because many people can have the same name. So a Dictionary will always, at most, map to a single value.

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

A Lookup will map to potentially several values.

查找将映射到潜在的多个值。

Lookup["Smith"]["John"] will be a collection of size one billion.

Lookup["Smith"]["John"] 将是一个大小为 10 亿的集合。

回答by jwg

One use of Lookupcould be to reverse a Dictionary.

的一种用途Lookup可能是反转Dictionary.

Suppose you have a phonebook implemented as a Dictionarywith a bunch of (unique) names as keys, each name associated with a phone number. But two people with different names might share the same phone number. This isn't a problem for a Dictionary, which doesn't care that two keys correspond to the same value.

假设您有一个电话簿Dictionary,以一堆(唯一的)名称作为键,每个名称都与一个电话号码相关联。但是两个名字不同的人可能会共享同一个电话号码。这对 a 来说不是问题Dictionary,它不在乎两个键对应于相同的值。

Now you want a way of looking up who a given phone number belongs to. You build a Lookup, adding all the KeyValuePairsfrom your Dictionary, but backwards, with the value as the key and the key as the value. You can now query a phone number, and obtain a list of names of all the people whose phone number that is. Building a Dictionarywith the same data would drop data (or fail, depending on how you did it), since doing

现在您想要一种查找给定电话号码属于谁的方法。您构建了一个LookupKeyValuePairs从您的Dictionary,但向后添加所有,以值作为键,键作为值。您现在可以查询一个电话号码,并获得该电话号码的所有人的姓名列表。Dictionary使用相同的数据构建一个会丢失数据(或失败,取决于你是如何做的),因为这样做

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

means that the second entry overwrites the first - the Doc is no longer listed.

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

Trying to write the same data in a slightly different way:

尝试以稍微不同的方式写入相同的数据:

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

would throw an exception on the second line since you can't Adda key which is already in the Dictionary.

将在第二行抛出异常,因为您不能Add使用已经在Dictionary.

[Of course, you might want to use some other single data structure to do lookups in both directions, etc. This example means that you have to regenerate the Lookupfrom the Dictionaryeach time the latter changes. But for some data it could be the right solution.]

[当然,您可能希望使用其他一些单一数据结构在两个方向上进行查找等。此示例意味着您必须LookupDictionary每次后者更改时从重新生成。但对于某些数据,它可能是正确的解决方案。]