c# - Lookup<TKey,TElement>的要點是什麼?




.net linq (4)

Lookup一種用法可能是翻轉Dictionary

假設你有一個電話簿實現為一個Dictionary ,有一堆(唯一)名稱作為鍵,每個名字與一個電話號碼相關聯。 但是名稱不同的兩個人可能共享相同的電話號碼。 這對Dictionary不是問題,它不關心兩個鍵對應相同的值。

現在,您需要查找給定電話號碼所屬的人的方式。 您創建一個Lookup ,從Dictionary添加所有的KeyValuePairs ,但是向後,將值作為關鍵字,將關鍵字作為值。 您現在可以查詢電話號碼,並獲取所有電話號碼為的人員的名單。 建立一個具有相同數據的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的鍵。

[當然,您可能希望使用其他單一數據結構在兩個方向上執行查找等。此示例意味著每次後者更改時都必須從Dictionary重新生成Lookup 。 但對於一些數據來說,這可能是正確的解決方案。]

MSDN解釋如下所示:

Lookup<TKey, TElement>類似於Dictionary<TKey, TValue> 。 區別在於Dictionary <TKey,TValue>將鍵映射到單個值,而查找<TKey,TElement>將鍵映射到值集合。

我不覺得這個解釋特別有用。 Lookup用於什麼?


一種想法是這樣的: 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());
        }
    }
}

我想你可以這樣爭論:想像你正在創建一個數據結構來保存電話簿的內容。 你想按lastName鍵,然後按firstName鍵。 在這裡使用字典會很危險,因為很多人可以擁有相同的名字。 因此,一本詞典至多會映射到一個單一的值。

查找將映射到可能的幾個值。

查詢[“史密斯”] [“約翰”]將是一個十億大小的集合。


這是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