Was ist der Punkt der Lookup ?
Frage
Der MSDN erklärt Lookup wie folgt aus:
Lookup<TKey, TElement>
ähnelt einemDictionary<TKey, TValue>
. Der Unterschied besteht darin, dass ein WörterbuchKarten Tasten auf einzelne Werte, während ein Lookup Karten Schlüssel zu einer Sammlung von Werten.
Ich finde nicht, dass Erklärung besonders hilfreich. Was ist Lookup verwendet?
Lösung
Es ist eine Kreuzung zwischen einem IGrouping
und einem Wörterbuch. Es ermöglicht Ihnen Gruppenelemente zusammen mit einem Schlüssel, aber sie dann auf effiziente Weise über diesen Schlüssel zugreifen (und nicht nur Iterieren über sie alle, das ist, was GroupBy
können Sie tun).
Zum Beispiel können Sie eine Last von .NET-Typen nehmen und einen Lookup durch Namespace bauen ... dann bekommen auf alle Arten in einem bestimmten Namensraum sehr leicht:
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 normalerweise var
für die meisten dieser Erklärungen, in normalen Code verwenden würde.)
Andere Tipps
Eine Möglichkeit, darüber nachzudenken, ist dies: Lookup<TKey, TElement>
ähnlich ist Dictionary<TKey, Collection<TElement>>
. Im Grunde eine Liste von null oder mehr Elementen kann über den gleichen Schlüssel zurückgegeben werden.
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
}
}
}
Eine Verwendung von Lookup
könnte ein Dictionary
umkehren.
Angenommen, Sie ein Telefonbuch als Dictionary
mit einem Bündel von (eindeutigen) Namen als Schlüssel implementiert haben, jeden Namen mit einer Telefonnummer zugeordnet ist. Aber zwei Personen mit unterschiedlichen Namen könnten die gleiche Telefonnummer teilen. Dies ist kein Problem für eine Dictionary
, das nicht, dass zwei Tasten auf den gleichen Wert entsprechen schert.
Sie möchten nun einen Weg des Nachschlagens, die eine bestimmte Telefonnummer gehört. Sie bauen eine Lookup
und fügte hinzu, alle KeyValuePairs
von Ihrem Dictionary
, aber nach hinten, wobei der Wert als Schlüssel und den Schlüssel als Wert. Sie können nun eine Telefonnummer abfragen und eine Liste der Namen aller Personen, deren Telefonnummer erhalten, das ist. Der Aufbau einer Dictionary
mit den gleichen Daten würden Daten fallen (oder ausfallen, je nachdem, wie Sie es getan haben), da tun
dictionary["555-6593"] = "Dr. Emmett Brown";
dictionary["555-6593"] = "Marty McFly";
bedeutet, dass der zweite Eintrag überschreibt die erste -. Der Doc nicht mehr aufgeführt
Der Versuch, die gleichen Daten auf eine etwas andere Art und Weise zu schreiben:
dictionary.Add("555-6593", "Dr. Emmett Brown");
dictionary.Add("555-6593", "Marty McFly");
würde eine Ausnahme in der zweiten Zeile werfen, da Sie nicht einen Schlüssel, der in den Add
bereits Dictionary
können.
[Natürlich könnten Sie eine andere einzelne Datenstruktur verwenden mögen Lookups in beiden Richtungen zu tun, usw. Dieses Beispiel bedeutet, dass Sie die Lookup
vom Dictionary
jedes Mal der letztere Änderungen zu regenerieren haben. Aber für einige Daten könnte es die richtige Lösung sein.]
Ich habe nicht erfolgreich es vorher benutzt, aber hier ist mein gehen:
Ein Lookup<TKey, TElement>
wäre ziemlich ähnlich wie ein (relationaler) Datenbankindex auf einem Tisch ohne eindeutige Einschränkung verhalten. Verwenden Sie es an den gleichen Stellen würden Sie die andere verwenden.
Ich denke, man könnte es so argumentieren: stellen Sie eine Datenstruktur sind die Erstellung, den Inhalt eines Telefonbuch zu halten. Sie wollen von Nachnamen und dann durch Vornamen einzugeben. ein Wörterbuch hier unter Verwendung wäre gefährlich, weil viele Menschen den gleichen Namen haben. So wird ein Wörterbuch immer auf höchstens Karte auf einen einzigen Wert.
Eine Lookup potenziell mehrere Werte abbildet.
Lookup [ "Smith"] [ "John"] wird eine Sammlung von Größe einer Milliarde sein.