Neu in .NET 9.0 [22]: LINQ-Operator CountBy()
Ein neuer Operator für Language Integrated Query vereinfacht das Gruppieren nach Häufigkeit.
(Bild: Pincasso/Shutterstock.com)
- Dr. Holger Schwichtenberg
In .NET 9.0 hat Microsoft in der Basisklassenbibliothek den neuen Operator CountBy() für Language Integrated Query (LINQ) hinzugefügt. Wenn nach Häufigkeit gruppiert werden soll, ist es damit nicht mehr nötig, den Operator GroupBy() einzusetzen.
Videos by heise
Folgendes Codebeispiel ermittelt die häufigsten Vornamen mit CountBy():
private static List<Person> GetData()
{
#region ---------------- Demodaten erstellen
int count = 10000;
CUI.H3($"Generiere {count} Demodaten...");
Randomizer.Seed = new Random(42); // Fester Seed fĂĽr gleichbleibende Testdaten!
var personFaker = new AutoFaker<Person>("de") // Fake-Daten mit https://github.com/nickdodd79/AutoBogus
.RuleFor(fake => fake.ID, fake => fake.Random.Int(0))
.RuleFor(fake => fake.Givenname, fake => fake.Name.FirstName())
.RuleFor(fake => fake.Surname, fake => fake.Name.LastName())
.RuleFor(fake => fake.Birthday, fake => fake.Date.Past(100).Date)
.RuleFor(fake => fake.Team, fake => fake.Random.ArrayElement(new string[] { "MSV", "RWE", "BVB" }))
.RuleFor(fake => fake.Punkte, fake => fake.Random.Number(0, 10));
List<Person> personSet = new();
for (int i = 0; i < count; i++)
{
var p = personFaker.Generate();
personSet.Add(p);
}
Console.WriteLine("Anzahl Personen: " + personSet.Count);
#endregion
return personSet;
}
/// <summary>
/// Ermitteln der 10 häufigsten Vornamen in einer Liste von Personen
/// </summary>
public void LINQ_CountBy()
{
CUI.Demo(nameof(LINQ_CountBy) + ": Ermitteln der 10 häufigsten Vornamen in einer Liste von Personen");
List<Person> personSet = GetData();
// --------------------------- ALT
CUI.H2("10 häufigste Vornamen im Datenbestand (alt mit GroupBy() + Select())");
// bisherige Implementierung mit GroupBy() + Select()
var nameGroupsOld = personSet
.GroupBy(info => info.Givenname) // Gruppieren nach Häufigkeit des GivenName
.Select(group => new
{
Key = group.Key,
Value = group.Count() // Zählen
});
var groups1top10 = nameGroupsOld.OrderByDescending(x => x.Value).Take(10);
// Ausgabe mit SpectreConsole
AnsiConsole.Write(new BarChart()
.Width(60)
.AddItems(groups1top10, (item) => new BarChartItem(
item.Key, item.Value, Color.Cyan1)));
// --------------------------- NEU
CUI.H2("\n10 häufigste Vornamen im Datenbestand (neu mit CountBy())");
Dictionary<string, int> nameGroupsNew = personSet
.CountBy(x => x.Givenname); // Gruppieren nach Häufigkeit des GivenName
Console.WriteLine("10 häufigste Vornamen im Datenbestand:");
var groups2top10 = nameGroupsNew.OrderByDescending(x => x.Value).Take(10);
// Ausgabe mit SpectreConsole
AnsiConsole.Write(new BarChart()
.Width(60)
.AddItems(groups2top10, (item) => new BarChartItem(
item.Key, item.Value, Color.Cyan2)));
}
Das Ergebnis von CountBy() ist Dictionary<T, T>, während die bisherige Umsetzung mit GroupBy() einen anonymen Typ liefert.
(Bild:Â Screenshot (Holger Schwichtenberg))
(rme)