В чем смысл поиска?
MSDN объясняет Поиск следующим образом:
A
Lookup<TKey, TElement>
напоминаетDictionary<TKey, TValue>
. Разница в том, что Словарь сопоставляет ключи с отдельными значениями, в то время как a Lookup сопоставляет ключи с коллекциями значений.
Я не нахожу это объяснение особенно полезным. Для чего используется поиск?
5 ответов:
это нечто среднее между
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<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()); } } }
использование
Lookup
может быть, чтобы отменить aDictionary
.Предположим, у вас есть телефонная книга реализована как
Dictionary
с кучей (уникальных) имен в качестве ключей, каждое имя, связанное с номером телефона. Но два человека с разными именами могут иметь один и тот же номер телефона. Это не проблема дляDictionary
, который не заботится о том, что два ключа соответствуют одному и тому же значению.теперь вы хотите, чтобы взглянуть, кто данный номер телефона принадлежит. Вы строите
Lookup
, сложив всеKeyValuePairs
из своегоDictionary
, но в обратном направлении, со значением в качестве ключа и ключ в качестве значения. Теперь вы можете запросить номер телефона и получить список имен всех людей, чей номер телефона это. СтроительствоDictionary
С теми же данными будет падение данных (или сбой, в зависимости от того, как вы это сделали), так как делатьdictionary["555-6593"] = "Dr. Emmett Brown"; dictionary["555-6593"] = "Marty McFly";
означает, что вторая запись перезаписывает первую - документ больше не указан.
попытка записать те же данные в a немного по-другому:
dictionary.Add("555-6593", "Dr. Emmett Brown"); dictionary.Add("555-6593", "Marty McFly");
вызовет исключение на второй строке, так как вы не можете
Add
ключ, который уже находится вDictionary
.[конечно, вы можете использовать какую-то другую единую структуру данных для поиска в обоих направлениях и т. д. Этот пример означает, что вы должны восстановить
Lookup
СDictionary
каждый раз последние изменения. Но для некоторых данных это может быть правильным решением.]
Я не успешно использовал его раньше, но вот мой go:
A
Lookup<TKey, TElement>
будет вести себя в значительной степени как (реляционный) индекс базы данных в таблице без уникального ограничения. Используйте его в тех же местах, где вы использовали бы другой.
Я думаю, вы можете утверждать это так: представьте, что вы создаете структуру данных для хранения содержимого телефонной книги. Вы хотите, чтобы ключ по фамилии, а затем по имени. Использование словаря было бы опасно, потому что многие люди могут иметь одинаковые имена. Таким образом, словарь всегда будет, самое большее, сопоставляться с одним значением.
поиск будет сопоставляться с потенциально несколькими значениями.
Lookup ["Smith"] ["John"] будет коллекция размером один миллиард.