To skrzyżowanie IGrouping
słownika i słownika. Pozwala grupować elementy razem według klucza, ale następnie uzyskiwać do nich dostęp za pomocą tego klucza w efektywny sposób (zamiast po prostu iterować je wszystkie, co GroupBy
pozwala na to).
Na przykład, możesz wziąć ładunek typów .NET i utworzyć wyszukiwanie według przestrzeni nazw ... a następnie bardzo łatwo uzyskać dostęp do wszystkich typów w określonej przestrzeni nazw:
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);
}
}
}
(Zwykle używałbym var
dla większości tych deklaracji, w normalnym kodzie.)
Lookup<,>
to po prostu niezmienna kolekcja (bezAdd
metody np.), Która ma ograniczone zastosowanie. Co więcej, nie jest to zbiór ogólnego przeznaczenia w tym sensie, że jeśli wyszukasz nieistniejący klucz, otrzymasz pustą sekwencję zamiast wyjątku, co ma znaczenie tylko w specjalnych kontekstach, na przykład w linq. Zgadza się to z faktem, że firma MS nie udostępniła publicznego konstruktora dla tej klasy.Można o tym pomyśleć:
Lookup<TKey, TElement>
jest podobny doDictionary<TKey, Collection<TElement>>
. Zasadniczo lista zawierająca zero lub więcej elementów może zostać zwrócona za pomocą tego samego klucza.źródło
Jednym z zastosowań
Lookup
może być odwrócenie plikuDictionary
.Załóżmy, że masz książkę telefoniczną zaimplementowaną jako zestaw
Dictionary
(unikalnych) nazw jako kluczy, z których każda jest powiązana z numerem telefonu. Ale dwie osoby o różnych nazwach mogą mieć ten sam numer telefonu. Nie stanowi to problemu dla aDictionary
, który nie przejmuje się tym, że dwa klucze odpowiadają tej samej wartości.Teraz potrzebujesz sposobu na sprawdzenie, do kogo należy dany numer telefonu. Budujesz
Lookup
, dodając wszystkieKeyValuePairs
z twojegoDictionary
, ale wstecz, z wartością jako kluczem i kluczem jako wartością. Możesz teraz zapytać o numer telefonu i uzyskać listę nazwisk wszystkich osób, których to numer telefonu. BudowanieDictionary
z tymi samymi danymi spadnie dane (lub nie, w zależności od tego, jak to zrobił), ponieważ robioznacza, że drugi wpis zastępuje pierwszy - dokumentu nie ma już na liście.
Próbuję zapisać te same dane w nieco inny sposób:
zgłosiłby wyjątek w drugiej linii, ponieważ nie można
Add
użyć klucza, który jest już wDictionary
.[Oczywiście, możesz chcieć użyć jakiejś innej pojedynczej struktury danych do wyszukiwania w obu kierunkach, itd. Ten przykład oznacza, że musisz ponownie wygenerować dane
Lookup
zDictionary
każdej zmiany tej ostatniej. Ale w przypadku niektórych danych może to być właściwe rozwiązanie.]źródło
Nie korzystałem z niego wcześniej, ale oto moja kolej:
A
Lookup<TKey, TElement>
zachowywałby się prawie jak (relacyjny) indeks bazy danych w tabeli bez ograniczenia unikalności. Użyj go w tych samych miejscach, w których używałbyś drugiego.źródło
Myślę, że można to argumentować w ten sposób: wyobraź sobie, że tworzysz strukturę danych do przechowywania zawartości książki telefonicznej. Chcesz wprowadzić klucz przez lastName, a następnie przez firstName. Używanie tutaj słownika byłoby niebezpieczne, ponieważ wiele osób może mieć to samo imię. Zatem słownik zawsze będzie mapował co najwyżej pojedynczą wartość.
Lookup mapuje potencjalnie kilka wartości.
Lookup [„Smith”] [„John”] będzie zbiorem o wielkości jednego miliarda.
źródło
Lookup["Smith"]["John"]
?