ToDictionary / ToLookup în C# (.NET)

LINQ (Language Integrated Query) .NET Framework 3.5 (ToDictionary() fără parametri: .NET 8)

Transformă o secvență într-un Dictionary (o valoare per cheie) sau într-un ILookup (mai multe valori per cheie), pentru căutare rapidă.

Sintaxă C#
sursa.ToDictionary(x => x.Cheie)   sursa.ToDictionary(x => x.Cheie, x => x.Valoare)   sursa.ToLookup(x => x.Grup)

Ce face ToDictionary / ToLookup

ToDictionary parcurge secvența imediat și construiește un Dictionary<TKey, TValue>. Cu un singur selector, valoarea este elementul întreg; cu doi, alegi și valoarea. Cheile trebuie să fie unice: o cheie repetată aruncă ArgumentException. Din .NET 8, o secvență de KeyValuePair sau de tuple-uri cu două elemente se transformă direct, cu ToDictionary().

ToLookup grupează elementele după cheie, ca GroupBy, dar imediat și cu acces după cheie: lookup["IT"] întoarce toate elementele grupului. O cheie care nu există dă o secvență goală, nu o excepție.

Parametri

Parametru Descriere
keySelector Funcția care dă cheia fiecărui element.
elementSelector Opțional: valoarea salvată pentru cheie.
comparer Opțional: de exemplu StringComparer.OrdinalIgnoreCase.

Exemple

Exemplul 1: Dicționar după cod și lookup după categorie

Produs[] produse =
[
    new("P1", "Laptop", "IT", 3500),
    new("P2", "Mouse", "IT", 80),
    new("P3", "Cafea", "Alimente", 35),
];

var dupaCod = produse.ToDictionary(p => p.Cod);
Console.WriteLine(dupaCod["P2"].Nume);

var preturi = produse.ToDictionary(p => p.Nume, p => p.Pret);
Console.WriteLine(preturi["Cafea"]);

var peCategorii = produse.ToLookup(p => p.Categorie);
Console.WriteLine(string.Join(", ", peCategorii["IT"].Select(p => p.Nume)));
Console.WriteLine(peCategorii["Jucării"].Count());

record Produs(string Cod, string Nume, string Categorie, int Pret);

Rezultat

Mouse
35
Laptop, Mouse
0

Exemplul 2: Chei duplicate și ToDictionary() din .NET 8

string[] orase = ["Iași", "Cluj", "Iași"];

try
{
    var d = orase.ToDictionary(o => o);
}
catch (ArgumentException)
{
    Console.WriteLine("Cheie duplicată");
}

var numarate = orase.GroupBy(o => o).ToDictionary(g => g.Key, g => g.Count());
Console.WriteLine(numarate["Iași"]);

var mari = numarate.Where(kv => kv.Value > 1).ToDictionary();
Console.WriteLine(string.Join(", ", mari.Keys));

Rezultat

Cheie duplicată
2
Iași

Greșeli frecvente

  • ToDictionary pe date cu chei repetate (de exemplu nume de clienți) aruncă excepție. Grupează înainte sau folosește ToLookup.
  • dictionar[cheie] pentru o cheie lipsă aruncă KeyNotFoundException, spre deosebire de lookup[cheie], care dă o secvență goală.

Comenzi înrudite

  • CountBy, AggregateBy și Index (.NET 9): CountBy numără elementele pe chei, AggregateBy calculează un total pe chei, iar Index dă poziția fiecărui element, fără GroupBy.
  • Distinct / DistinctBy: Elimină duplicatele dintr-o secvență; DistinctBy compară după o cheie (de exemplu clientul) și păstrează primul element.