Question

Le MSDN explique Lookup comme ceci:

  

Une Rechercher < TKey, TElement >   ressemble à un dictionnaire < TKey,   TValue > . La différence est que    Dictionnaire mappe les clés sur des valeurs uniques, alors qu'un    Lookup < TKey, TElement > mappe les clés sur des collections de valeurs.

Je ne trouve pas cette explication particulièrement utile. À quoi sert Lookup?

Était-ce utile?

La solution

C'est un croisement entre un IGrouping et un dictionnaire. Il vous permet de regrouper des éléments à l'aide d'une clé, mais d'y accéder de manière efficace via cette clé (plutôt que de simplement les parcourir tous, comme le permet GroupBy ).

Par exemple, vous pouvez utiliser une charge de types .NET et créer une recherche par espace de noms ... puis accéder à tous les types d'un espace de noms particulier très facilement:

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

(J'utiliserais normalement var pour la plupart de ces déclarations, en code normal.)

Autres conseils

Une façon de penser à cela est la suivante: Lookup < TKey, TElement & est similaire à Dictionnaire < TKey, Collection < TElement > > . En principe, une liste de zéro ou plusieurs éléments peut être renvoyée via la même clé.

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

Une des utilisations de Lookup pourrait être d'inverser un dictionnaire .

Supposons qu'un répertoire est implémenté en tant que Dictionnaire avec un groupe de noms (uniques) comme clés, chaque nom associé à un numéro de téléphone. Mais deux personnes avec des noms différents peuvent partager le même numéro de téléphone. Ce n'est pas un problème pour un dictionnaire , peu importe que deux clés correspondent à la même valeur.

Maintenant, vous voulez un moyen de rechercher à qui appartient un numéro de téléphone donné. Vous créez une Lookup , en ajoutant tous les KeyValuePairs à partir de votre Dictionnaire , mais à l'envers, avec la valeur comme clé et la clé comme valeur. Vous pouvez maintenant interroger un numéro de téléphone et obtenir une liste des noms de toutes les personnes dont le numéro est. Construire un dictionnaire avec les mêmes données lâcherait des données (ou échouerait, selon la façon dont vous l'avez fait), car

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

signifie que la deuxième entrée remplace la première - le document n'est plus répertorié.

Essayer d'écrire les mêmes données d'une manière légèrement différente:

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

lancera une exception sur la deuxième ligne car vous ne pouvez pas ajouter une clé qui se trouve déjà dans le dictionnaire .

[Bien sûr, vous pouvez utiliser une autre structure de données unique pour effectuer des recherches dans les deux sens, etc. Cet exemple signifie que vous devez régénérer le Lookup à partir du Dictionnaire chaque fois que ce dernier change. Mais pour certaines données, cela pourrait être la bonne solution.]

Je ne l'ai pas utilisé avec succès auparavant, mais voici mon tour:

Un Lookup < TKey, TElement > se comporterait presque comme un index de base de données (relationnelle) sur une table sans contrainte unique. Utilisez-le aux mêmes endroits que vous utiliseriez l'autre.

Je suppose que vous pourriez le dire de la manière suivante: imaginez que vous créez une structure de données pour contenir le contenu d'un annuaire téléphonique. Vous voulez taper par lastName, puis par firstName. Utiliser un dictionnaire ici serait dangereux car beaucoup de gens peuvent avoir le même nom. Ainsi, un dictionnaire sera toujours, au plus, mappé à une valeur unique.

Une recherche mappera potentiellement plusieurs valeurs.

Lookup ["Smith"] ["John"] constituera une collection d'un milliard.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top