Sie sind hier: Weblog

Neu in .NET 6 [6]: LINQ-Operator DistinctBy()

Foto Dr. Holger Schwichtenberg, Dr. Holger Schwichtenberg
17.11.2021 08:32:00

Die Serie zu den Neuerungen in .NET 6 behandelt im sechsten Teil einen Operator zum Entfernen von Duplikaten.

Seit der ersten Version der Language Integrated Query (LINQ) aus dem Jahre 2007 kennt .NET den Operator Distinct(), der aus einer gegebenen Menge von Objekten alle Duplikate eliminiert.

Folgender Programmcode filtert aus einer Menge von zufällig erzeugter Zahlen alle Duplikate heraus:

List<int> Zufallszahlen = Enumerable.Range(0, 100)
.Select(r => _rand.Next(20))
.ToList();
Console.WriteLine(
$"Erzeugte Zufallszahlen: {Zufallszahlen.Count}");

List<int> EindeutigeZufallszahlen =
Zufallszahlen.Distinct().ToList();
Console.WriteLine(
$"Eindeutige Zufallszahlen: {EindeutigeZufallszahlen.Count}");

Der neue DistinctBy()-Operator in .NET 6 hat einen zusätzlichen Parameter keySelector, dem man eine Funktion als Kriterium für die Duplikaterkennung übergeben kann. In Bezug auf die obige Zahlenliste ist das nicht sinnvoll, weil die Zahl das einzige Kriterium ist:

Für den Fall liefert DistinctBy()

List<int> EindeutigeZufallszahlen2 = 
Zufallszahlen.DistinctBy(x=>x).ToList();

dasselbe Ergebnis wie Distinct().

Sinnvoll lässt sich DistinctBy() dagegen bei einer Menge komplexer Objekte verwenden wie bei folgender Liste von Tupel aus Namen und Farben:

var personen = new (string Name, string Farbe)[] {
("Annalena", "grün"),
("Olaf", "rot"),
("Norbert", "rot"),
("Saskia", "rot"),
("Robert", "grün"),
("Armin", "schwarz"),
("Christian", "gelb") };

Dafür gibt

personen.Distinct().ToList();

eine Menge zurück, die der Ausgangsmenge entspricht, da jedes Element der Liste eindeutig ist.

Dagegen liefert der Aufruf von

personen.DistinctBy(x=>x.Farbe).ToList();

pro Farbe nur ein Objekt. DistinctBy() liefert jeweils das erste gefundene Objekt. In diesem Fall also:

(Annalena, grün)
(Olaf, rot)
(Armin, schwarz)
(Christian, gelb) ()