В чем смысл поиска?


MSDN объясняет Поиск следующим образом:

A Lookup<TKey, TElement> напоминает Dictionary<TKey, TValue>. Разница в том, что Словарь сопоставляет ключи с отдельными значениями, в то время как a Lookup сопоставляет ключи с коллекциями значений.

Я не нахожу это объяснение особенно полезным. Для чего используется поиск?

5 127

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 может быть, чтобы отменить a Dictionary.

Предположим, у вас есть телефонная книга реализована как 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"] будет коллекция размером один миллиард.