Это нечто среднее между 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<,>
- это просто неизменяемая коллекция (Add
например, без метода), которая имеет ограниченное использование. Кроме того, он не является коллекцией общего назначения в том смысле, что если вы выполняете поиск по несуществующему ключу, вы получаете пустую последовательность, а не исключение, которое имеет смысл только в особых контекстах, например, с linq. Это хорошо согласуется с тем фактом, что MS не предоставила открытый конструктор для класса.Один из способов думать об этом:
Lookup<TKey, TElement>
это похоже наDictionary<TKey, Collection<TElement>>
. По сути, список из нуля или более элементов может быть возвращен через один и тот же ключ.источник
Одним из применений
Lookup
может быть обратноеDictionary
.Предположим, у вас телефонная книга реализована в виде
Dictionary
набора (уникальных) имен в качестве ключей, каждое имя связано с номером телефона. Но два человека с разными именами могут использовать один и тот же номер телефона. Это не проблема для aDictionary
, которому все равно, что два ключа соответствуют одному значению.Теперь вам нужен способ узнать, кому принадлежит данный номер телефона. Вы строите
Lookup
, добавляя всеKeyValuePairs
от вашегоDictionary
, но в обратном направлении, со значением в качестве ключа и ключом в качестве значения. Теперь вы можете запросить номер телефона и получить список имен всех людей, чей номер телефона это. СборкаDictionary
с теми же данными приведет к удалению данных (или к сбою, в зависимости от того, как вы это сделали), посколькуозначает, что вторая запись перезаписывает первую - документа больше нет в списке.
Попытка записать одни и те же данные немного другим способом:
выдает исключение во второй строке, поскольку вы не можете
Add
найти ключ, который уже находится вDictionary
.[Конечно, вы можете использовать какую-то другую единую структуру данных для поиска в обоих направлениях и т. Д. Этот пример означает, что вам нужно регенерировать
Lookup
изDictionary
каждого изменения последнего. Но для некоторых данных это может быть правильным решением.]источник
Я не успешно использовал его раньше, но вот мой путь:
A
Lookup<TKey, TElement>
будет вести себя почти как (реляционный) индекс базы данных для таблицы без уникального ограничения. Используйте его в тех же местах, что и другие.источник
Полагаю, вы могли бы поспорить так: представьте, что вы создаете структуру данных для хранения содержимого телефонной книги. Вы хотите, чтобы ключ по lastName, а затем по firstName. Использование словаря здесь было бы опасно, потому что многие люди могут иметь одно и то же имя. Таким образом, словарь всегда будет максимально соответствовать одному значению.
Lookup отобразит потенциально несколько значений.
Lookup ["Смит"] ["Джон"] будет коллекция размером один миллиард.
источник
Lookup["Smith"]["John"]
?