Pergunta

O MSDN explica Lookup assim:

A Lookup<TKey, TElement> se assemelha a um Dictionary<TKey, TValue> . A diferença é que um Dictionary mapeia chaves para valores únicos, enquanto que um Lookup mapeia chaves para coleções de valores.

Eu não acho que a explicação particularmente útil. O que é Lookup utilizado?

Foi útil?

Solução

É um cruzamento entre um IGrouping e um dicionário. Ele permite que você agrupar itens por uma chave, mas, em seguida, acessá-los via que a chave de uma maneira eficiente (ao invés de apenas a iteração sobre todos eles, que é o que GroupBy permite que você faça).

Por exemplo, você poderia tomar uma carga de tipos .NET e construir uma pesquisa por namespace ... então chegar a todos os tipos em um namespace em particular com muita facilidade:

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);
        }
    }
}

(eu uso normalmente var para a maioria destas declarações, no código normal.)

Outras dicas

Uma maneira de pensar sobre isso é esta: Lookup<TKey, TElement> é semelhante ao Dictionary<TKey, Collection<TElement>>. Basicamente uma lista de zero ou mais elementos podem ser devolvidos através da mesma chave.

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
        }
    }
}

Um uso de Lookup poderia ser para reverter um Dictionary.

Suponha que você tem uma agenda implementado como um Dictionary com um monte de nomes (originais) como chaves, cada nome associado a um número de telefone. Mas duas pessoas com nomes diferentes podem compartilhar o mesmo número de telefone. Este não é um problema para um Dictionary, que não se importa que duas chaves correspondem ao mesmo valor.

Agora você quer uma maneira de olhar-se que um determinado número de telefone pertence. Você construir um Lookup, acrescentando todo o KeyValuePairs do seu Dictionary, mas para trás, com o valor como a chave e a chave como o valor. Agora você pode consultar um número de telefone, e obter uma lista de nomes de todas as pessoas cujo número de telefone que é. Construindo um Dictionary com os mesmos dados cairia de dados (ou não, dependendo de como você fez isso), uma vez fazendo

dictionary["555-6593"] = "Dr. Emmett Brown";
dictionary["555-6593"] = "Marty McFly";

significa que a segunda entrada substitui o primeiro -. O Doc não está listado

Tentando escrever os mesmos dados de uma forma ligeiramente diferente:

dictionary.Add("555-6593", "Dr. Emmett Brown");
dictionary.Add("555-6593", "Marty McFly");

iria lançar uma exceção na segunda linha desde que você não pode Add uma chave que já está no Dictionary.

[Claro, você pode querer usar alguma outra estrutura de dados única para fazer pesquisas em ambas as direções, etc. Este exemplo significa que você tem para regenerar o Lookup do Dictionary cada vez que as últimas alterações. Mas para alguns dados que poderia ser a solução certa.]

Eu nunca usei isso com êxito antes, mas aqui é a minha ir:

A Lookup<TKey, TElement> iria se comportar muito bem como um (relacional) índice de banco de dados em uma tabela sem uma restrição exclusiva. Usá-lo nos mesmos lugares que você usaria o outro.

Eu acho que você poderia argumentar desta forma: imagine que você está criando uma estrutura de dados para armazenar o conteúdo de um livro de telefone. Você quer chave, lastName e depois por firstName. Usando um dicionário aqui seria perigoso, porque muitas pessoas podem ter o mesmo nome. Assim, um dicionário sempre, no máximo, mapear para um único valor.

A pesquisa irá mapear para, potencialmente, vários valores.

Lookup [ "Smith"] [ "John"] será uma coleção de tamanho um bilhão.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top