Domanda

MSDN spiega Lookup in questo modo:

  

A Ricerca < TKey, TElement >   assomiglia a un Dictionary < TKey,   TValue > . La differenza è che a    Dizionario < TKey, TValue > mappa le chiavi su valori singoli, mentre un    Ricerca < TKey, TElement > mappa le chiavi su raccolte di valori.

Non trovo questa spiegazione particolarmente utile. A cosa serve la ricerca?

È stato utile?

Soluzione

È un incrocio tra un IGrouping e un dizionario. Ti consente di raggruppare gli elementi in base a una chiave, ma poi di accedervi tramite quella chiave in modo efficiente (anziché semplicemente iterandoli su tutti, che è ciò che GroupBy ti consente di fare).

Ad esempio, potresti prendere un sacco di tipi .NET e creare una ricerca per spazio dei nomi ... quindi arrivare a tutti i tipi in uno spazio dei nomi molto facilmente:

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

(normalmente userei var per la maggior parte di queste dichiarazioni, in codice normale.)

Altri suggerimenti

Un modo di pensarci è questo: Cerca < TKey, TElement > è simile a Dizionario < TKey, Collezione < TElement > > . Fondamentalmente un elenco di zero o più elementi può essere restituito tramite la stessa chiave.

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

Un uso di Ricerca potrebbe essere quello di invertire un Dizionario .

Supponi di avere una rubrica implementata come Dizionario con un mucchio di nomi (univoci) come chiavi, ogni nome associato a un numero di telefono. Ma due persone con nomi diversi potrebbero condividere lo stesso numero di telefono. Questo non è un problema per un Dizionario , a cui non importa che due chiavi corrispondano allo stesso valore.

Ora vuoi un modo per cercare a chi appartiene un determinato numero di telefono. Costruisci un Ricerca , aggiungendo tutti i KeyValuePairs dal tuo Dizionario , ma al contrario, con il valore come chiave e la chiave come valore. Ora puoi eseguire una query su un numero di telefono e ottenere un elenco di nomi di tutte le persone il cui numero di telefono è. Costruire un Dizionario con gli stessi dati eliminerebbe i dati (o fallirebbe, a seconda di come l'hai fatto), dal momento che lo hai fatto

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

significa che la seconda voce sovrascrive la prima - il Doc non è più elencato.

Prova di scrivere gli stessi dati in un modo leggermente diverso:

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

genererebbe un'eccezione sulla seconda riga poiché non è possibile Aggiungi una chiave che è già nel Dizionario .

[Ovviamente, potresti voler usare qualche altra singola struttura di dati per fare ricerche in entrambe le direzioni, ecc. Questo esempio significa che devi rigenerare il Ricerca dal Dizionario ogni volta che cambia quest'ultimo. Ma per alcuni dati potrebbe essere la soluzione giusta.]

Non l'ho mai usato con successo prima, ma ecco il mio go:

Una ricerca < TKey, TElement > si comporterebbe praticamente come un indice di database (relazionale) su una tabella senza un vincolo univoco. Usalo negli stessi posti in cui useresti l'altro.

Suppongo che potresti discuterne in questo modo: immagina di creare una struttura di dati per contenere i contenuti di una rubrica. Si desidera digitare da lastName e quindi da firstName. L'uso di un dizionario qui sarebbe pericoloso perché molte persone possono avere lo stesso nome. Quindi un dizionario sarà sempre, al massimo, associato a un singolo valore.

Una ricerca verrà mappata su potenzialmente diversi valori.

Ricerca [" Smith "] [" John "] sarà una raccolta di dimensioni di un miliardo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top