ILookup <TKey, TVal> vs. IGrouping <TKey, TVal>

hlasů
64

Byl jsem potíže artikulovat rozdíly mezi ILookup<TKey, TVal>a IGrouping<TKey, TVal>, a jsem zvědavý, jestli jsem to správně chápu. LINQ zhoršuje problém tím, že produkuje sekvence IGroupingbodů, zatímco mi také dávat si ToLookupmetodu rozšíření. Takže to pocit, jako by byly stejné, dokud se blíže podíval.

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

Což odpovídá:

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

Který vypadá jako:

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

Mám pravdu v těchto analogií?

  1. IGrouping<TKey, TVal>Je jediná skupina (tj klíčem sekvence), analogické KeyValuePair<TKey, TVal>, kde je tato hodnota ve skutečnosti sekvence prvků (spíše než jeden prvek)
  2. IEnumerable<IGrouping<TKey, TVal>>Je posloupnost těch (podobný tomu, co dostanete, když iterace přesIDictionary<TKey, TVal>
  3. ILookup<TKey, TVal>Je spíš jako IDictionary<TKey, TVal>kde je tato hodnota ve skutečnosti sekvence prvků
Položena 26/08/2009 v 22:16
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
64

Ano, všechny z nich jsou správné.

A ILookup<TKey, TValue>rovněž rozšiřuje IEnumerable<IGrouping<TKey, TValue>>, takže můžete iteraci všech párů klíč / sběru, jakož i (nebo místo), jen při pohledu do určité klávesy.

V podstatě jsem myslet ILookup<TKey,TValue>jako bytí jako IDictionary<TKey, IEnumerable<TValue>>.

Mějte na paměti, že ToLookupje „udělej to hned“ operace (okamžitý výkon), zatímco GroupByse odkládá. Jak se to stane, se způsobem, který „vytáhnout LINQ“ funguje, když začnete tahem IGroupingsz výsledek GroupBy, musí v každém případě přečíst všechna data (protože nemůžete přepnout skupina v polovině), zatímco v jiných implementacích může dojít k je schopen vyrobit výsledek streaming. (To dělá Push LINQ, očekával bych LINQ k událostem být stejné.)

Odpovězeno 26/08/2009 v 22:21
zdroj uživatelem

hlasů
8

Tam je další důležitý rozdíl mezi ILookup a IDictionary: bývalý vynucuje neměnnost v tom smyslu, že zde nejsou žádné metody pro změnu dat (kromě případů, kdy spotřebitel provádí explicitní nádech). Naproti tomu IDictionary má metody, jako je „Přidat“, které umožňují změnu dat. Takže z hlediska funkčního-programování a / nebo paralelní programování, ILookup je hezčí. (Jen jsem si tam byl také verze ILookup který přiřazuje pouze jednu hodnotu klíče spíše než ve skupině).

(. Mimochodem, zdá se poukázat na to, že vztah mezi IEnumerable a IList je poněkud podobný tomu, který mezi ILookup a IDictionary - první z nich je neměnný, druhý ne.)

Odpovězeno 05/06/2013 v 17:00
zdroj uživatelem

hlasů
0

GroupBya ToLookUpmá téměř stejnou funkcionalitu KROMĚ takto: Odkaz

GroupBy: Operátor GroupBy vrátí skupiny prvků založených na nějakou hodnotu klíče. Každá skupina je reprezentována IGrouping objektu.

ToLookup: ToLookup je stejný jako GroupBy; Jediným rozdílem je realizace GroupBy se odkládá, zatímco realizace ToLookup je okamžitá.

Umožňuje jasný rozdíl pomocí ukázkový kód. Domníváme se, že máme třídu představující Personmodelu:

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

poté, co jsme se definovat seznam personnelsjak je uvedeno níže:

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

Teď potřebuji, aby svou personnelsseskupeny podle jejich úrovně. Mám dva přístup zde. pomocí GroupBynebo ToLookUp. Mám-li použít GroupBy, jak bylo uvedeno výše, bude používat odložený výkon, to znamená, že když iterovat kolekce další bod může nebo nemusí být vypočítán tak, aby se nazývá pro.

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

Ve výše uvedeném kódu, to za prvé seskupil personnels, ale před iterací, já odstranit některé personnels. Jak GroupBypoužívá odložené provedení, takže konečný výsledek nebude obsahovat odstraněné položky, protože seskupení se výpočetní v foreachbodě zde.

Výstup:

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

Ale když jsem přepsat výše uvedený kód jak je uvedeno níže: (všimněte si, že kód je stejný jako v předchozím kódu s výjimkou GroupByje nahrazen 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);
    }

As ToLookUpvyužívá okamžitý výkon, to znamená, že když jsem volat ToLookUpmetodu, výsledek je generován a je použita skupina, takže když jsem odstranit jakoukoliv položku z personnelspřed iteraci zvyklý, že vliv na konečný výsledek.

Výstup:

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

Poznámka: GroupBya ToLookUpobě vrátí různé typy taky.

Dalo by se použít ToDictionary místo ToLookUp, ale musíte dávat pozor na to :( reference )

Využití ToLookup () je velmi podobný tomu ToDictionary (), oba umožňují zadat klíčové selektorů, hodnoty selektorů a comparers. Hlavním rozdílem je, že ToLookup () umožňuje (a očekává) duplicitní klíče, zatímco ToDictionary () není

Odpovězeno 08/08/2018 v 09:15
zdroj uživatelem

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