ILookup <TKey, tvål> contre IGrouping <TKey, tvål>

voix
64

J'ai eu du mal à articuler les différences entre ILookup<TKey, TVal>et IGrouping<TKey, TVal>, et je suis curieux de savoir si je comprends bien maintenant. LINQ aggravé le problème en produisant des séquences d' IGroupingarticles tout en me donnant une ToLookupméthode d'extension. On avait l' impression qu'ils étaient les mêmes jusqu'à ce que je regardais de plus près.

var q1 = 
    from n in N
    group n by n.MyKey into g
    select g;
// q1 is IEnumerable<IGrouping<TKey, TVal>>

Ce qui équivaut à:

var q2 = N.GroupBy(n => n.MyKey, n => n);
// q2 is IEnumerable<IGrouping<TKey, TVal>>

Ce qui ressemble beaucoup:

var q3 = N.ToLookup(n => n.MyKey, n => n);
// q3 is ILookup<TKey, TVal>

Ai-je raison dans les analogies suivantes?

  1. Un IGrouping<TKey, TVal>est un seul groupe ( par exemple une clé de séquence), analogue à KeyValuePair<TKey, TVal>laquelle la valeur est en fait une séquence d'éléments (plutôt que d' un seul élément)
  2. Une IEnumerable<IGrouping<TKey, TVal>>est une séquence de ceux (semblable à ce que vous obtenez lorsque vous parcourez uneIDictionary<TKey, TVal>
  3. Un ILookup<TKey, TVal>ressemble plus à un IDictionary<TKey, TVal>lorsque la valeur est en fait une séquence d'éléments
Créé 26/08/2009 à 22:16
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
64

Oui, tous ceux qui sont corrects.

Et ILookup<TKey, TValue>Prolonge aussi pour IEnumerable<IGrouping<TKey, TValue>>que vous puissiez itérer sur toutes les paires clé / collection, ainsi que (ou au lieu de) juste à la recherche des clés particulières.

Je pense fondamentalement ILookup<TKey,TValue>comme comme IDictionary<TKey, IEnumerable<TValue>>.

Gardez à l' esprit que ToLookupest une opération « faire maintenant » (exécution immédiate) alors qu'un GroupByest reporté. Comme il arrive, avec la façon dont « tirer LINQ » fonctionne, quand vous commencez à tirer IGroupings à partir du résultat d'un GroupBy, il faut lire toutes les données de toute façon (parce que vous ne pouvez pas changer le groupe à mi - chemin) , alors que dans d' autres mises en œuvre , il peut être en mesure de produire un résultat de streaming. (Il fait en push LINQ, je me attends LINQ aux événements d'être le même.)

Créé 26/08/2009 à 22:21
source utilisateur

voix
8

Il y a une autre différence importante entre iLookup et IDictionary: l'ancien immuabilité impose en ce sens que ucune méthodes pour modifier les données (sauf si le consommateur effectue un casting explicite). En revanche, IDictionary a des méthodes comme « Ajouter », qui permettent de modifier les données. Ainsi, dans la perspective de programmation fonctionnelle et / ou la programmation parallèle, iLookup est plus agréable. (Je veux seulement il y avait aussi une version de iLookup qui affecte une seule valeur à une clé plutôt que d'un groupe.)

(. BTW, il semble intéressant de souligner que la relation entre IEnumerable et IList est un peu semblable à celle entre iLookup et IDictionary - le premier est immuable, celle-ci est non.)

Créé 05/06/2013 à 17:00
source utilisateur

voix
0

GroupByet ToLookUpa presque la même fonctionnalité SAUF ceci: Référence

GroupBy: L'opérateur retourne GroupBy groupes d'éléments basés sur une valeur clé. Chaque groupe est représenté par l'objet IGrouping.

ToLookup: ToLookup est le même que GroupBy; la seule différence est l'exécution de GroupBy est différé tandis que l'exécution ToLookup est immédiate.

Permet d' effacer la différence en utilisant le code de l' échantillon. supposons que nous avons une classe qui représente le Personmodèle:

class Personnel
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public int Level { get; set; }
}

après que nous définissons une liste personnelscomme ci - dessous:

 var personnels = new List<Personnel>
    {
        new Personnel { Id = 1, FullName = "P1", Level = 1 },
        new Personnel { Id = 2, FullName = "P2", Level = 2 },
        new Personnel { Id = 3, FullName = "P3", Level = 1 },
        new Personnel { Id = 4, FullName = "P4", Level = 1 },
        new Personnel { Id = 5, FullName = "P5", Level =2 },
        new Personnel { Id = 6, FullName = "P6", Level = 2 },
        new Personnel { Id = 7, FullName = "P7", Level = 2 }
    };

Maintenant , je dois faire le personnelsregroupés par niveau. J'ai deux approche ici. en utilisant GroupByou ToLookUp. Si je l' utilise GroupBy, comme indiqué précédemment, il utilisera l' exécution différée, cela signifie que lorsque vous itérer la collection l'élément suivant peut ou ne peut pas être calculé jusqu'à ce qu'il soit appelé.

 var groups = personnels.GroupBy(p => p.Level);
    personnels.RemoveAll(p => p.Level == 1);
    foreach (var product in groups)
    {
        Console.WriteLine(product.Key);
        foreach (var item in product)
            Console.WriteLine(item.Id   " >>> "   item.FullName   " >>> "   item.Level);
    }

Dans le code ci - dessus, je tout d' abord regroupé les personnels, mais avant itérer, j'ai enlevé quelques personnels. Comme GroupByutilise l' exécution différée, de sorte que le résultat final ne comprend pas les éléments supprimés, parce que le regroupement sera de calcul , dans le foreachpoint de ici.

Sortie:

2
2 >>> P2 >>> 2
5 >>> P5 >>> 2
6 >>> P6 >>> 2
7 >>> P7 >>> 2

Mais si je réécris le code ci - dessus comme ci - dessous: (notez que le code est identique au code précédent , sauf GroupByest remplacé par ToLookUp)

 var groups = personnels.ToLookup(p => p.Level);
    personnels.RemoveAll(p => p.Level == 1);
    foreach (var product in groups)
    {
        Console.WriteLine(product.Key);
        foreach (var item in product)
            Console.WriteLine(item.Id   " >>> "   item.FullName   " >>> "   item.Level);
    }

Comme ToLookUputilise une exécution immédiate, cela signifie que lorsque j'appelle la ToLookUpméthode, le résultat est généré et le groupe est appliqué, de sorte que si je supprimer tout élément de personnelspréalable à l' itération, cet effet habitude le résultat final.

Sortie:

1
1 >>> P1 >>> 1
3 >>> P3 >>> 1
4 >>> P4 >>> 1
2
2 >>> P2 >>> 2
5 >>> P5 >>> 2
6 >>> P6 >>> 2
7 >>> P7 >>> 2

Note: GroupByet les ToLookUpdeux retournent différents types aussi.

Vous pouvez utiliser ToDictionary au lieu de ToLookup, mais vous devez prêter attention à cette :( référence )

L'utilisation de ToLookup () est très similaire à celle de ToDictionary (), tous deux vous permettent de spécifier les sélecteurs clés, sélecteurs de valeur et comparateurs. La principale différence est que ToLookup () permet (et attend) les clés en double alors que ToDictionary () ne

Créé 08/08/2018 à 09:15
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more