170

MSDN はルックアップを次のように説明しています。

ALookup<TKey, TElement> は に似ていDictionary<TKey, TValue>ます。違いは、 Dictionary<TKey, TValue>はキーを単一の値にマップするのに対し、 Lookup<TKey, TElement>はキーを値のコレクションにマップすることです。

その説明は特に役に立ちません。ルックアップは何に使用されますか?

4

5 に答える 5

231

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、通常のコードでは、これらの宣言のほとんどに使用します。)

于 2009-09-10T05:24:03.360 に答える
67

これについて考える 1 つの方法は次のとおりLookup<TKey, TElement>ですDictionary<TKey, Collection<TElement>>。基本的に、0 個以上の要素のリストを同じキーで返すことができます。

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
        }
    }
}
于 2009-09-10T05:24:53.030 に答える
33

の用途の 1 つは、Lookupを逆にすることDictionaryです。

Dictionary一連の (一意の) 名前をキーとして持つとして実装された電話帳があり、それぞれの名前が電話番号に関連付けられているとします。ただし、名前が異なる 2 人が同じ電話番号を共有している場合があります。Dictionaryこれは、2 つのキーが同じ値に対応することを気にしないにとっては問題ではありません。

ここで、特定の電話番号が誰のものであるかを検索する方法が必要になります。を構築しLookup、 からすべてを追加KeyValuePairsしますDictionaryが、値をキーとして、キーを値として逆方向に追加します。電話番号を照会して、その電話番号を持つすべての人の名前のリストを取得できるようになりました。同じデータで を構築するDictionaryと、データが削除されます (または、やり方によっては失敗します)。

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

2 番目のエントリが最初のエントリを上書きすることを意味します - Doc はもはやリストされていません。

少し異なる方法で同じデータを書き込もうとしています:

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

AddすでにDictionary. _

[もちろん、他の単一のデータ構造を使用して、双方向でルックアップを行うこともできます。この例は、後者が変更されるたびにLookupからを再生成する必要があることを意味します。Dictionaryしかし、一部のデータでは、それが正しい解決策になる可能性があります。]

于 2013-07-08T11:21:05.333 に答える
16

私は以前にそれをうまく使用したことがありませんが、ここに私の行き方があります:

は、一意制約のLookup<TKey, TElement>ないテーブルの (リレーショナル) データベース インデックスとほとんど同じように動作します。他のものと同じ場所で使用してください。

于 2009-09-10T05:24:22.320 に答える
5

電話帳の内容を保持するためのデータ構造を作成していると想像してください。lastName でキーを設定し、次に firstName でキーを設定します。ここで辞書を使うのは危険です。同じ名前の人がたくさんいる可能性があるからです。そのため、ディクショナリは常に、せいぜい単一の値にマップされます。

ルックアップは潜在的に複数の値にマップされます。

Lookup["Smith"]["John"] はサイズが 10 億のコレクションになります。

于 2009-09-10T05:26:03.457 に答える