446 Stimmen

C# Linq Gruppierung nach mehreren Spalten

public class ConsolidatedChild
{
    public string Schule { get; set; }
    public string Freund { get; set; }
    public string Lieblingsfarbe { get; set; }
    public List Kinder { get; set; }
}

public class Child
{
    public string Schule { get; set; }
    public string Name { get; set; }
    public string Adresse { get; set; }
    public string Freund { get; set; }
    public string Mutter { get; set; }
    public string Lieblingsfarbe { get; set; }
}

Angesichts der beiden obigen Klassen möchte ich LINQ verwenden, um eine Liste aus der Liste zu erstellen, gruppiert nach den Eigenschaften Schule, Freund und Lieblingsfarbe. Ist das mit LINQ möglich?

Bitte ignorieren Sie die Eigenschaften, der Code wurde nur geschrieben, um bei der Frage zu helfen.

1 Stimmen

Ja, es ist möglich. Schau dir das Beispiel in diesem Beitrag an.

2 Stimmen

Hier ist ein weiteres gutes Beispiel stackoverflow.com/questions/15605468/…

737voto

Enigmativity Punkte 104081
var consolidatedChildren =
    children
        .GroupBy(c => new
        {
            c.School,
            c.Friend,
            c.FavoriteColor,
        })
        .Select(gcs => new ConsolidatedChild()
        {
            School = gcs.Key.School,
            Friend = gcs.Key.Friend,
            FavoriteColor = gcs.Key.FavoriteColor,
            Children = gcs.ToList(),
        });

var consolidatedChildren =
    from c in children
    group c by new
    {
        c.School,
        c.Friend,
        c.FavoriteColor,
    } into gcs
    select new ConsolidatedChild()
    {
        School = gcs.Key.School,
        Friend = gcs.Key.Friend,
        FavoriteColor = gcs.Key.FavoriteColor,
        Children = gcs.ToList(),
    };

3 Stimmen

Angenommen, ich habe viele Eigenschaften in der Gruppierung, gibt es einen saubereren Weg, dies zu tun, als alle Eigenschaften aufzulisten?

4 Stimmen

@guiomie - Ich würde nicht sagen, dass es einen saubereren Weg gibt. Sie könnten das Objekt in einen einzelnen String serialisieren und danach gruppieren, aber das würde an anderer Stelle mehr Code erfordern. In meinen Augen ist diese Antwort daher der sauberste Weg, unabhängig von der Anzahl der Eigenschaften.

3 Stimmen

@Doppelganger - Ich habe deine Bearbeitung aus zwei Gründen zurückgesetzt. Die Entscheidung, das abschließende Komma (nach FavoriteColor) zu verwenden, erfolgt absichtlich - es ist eine gültige Syntax und erleichtert das Refactoring des Codes. Die Entscheidung, gcs anstelle von gc für die Gruppierungsvariable zu verwenden, ist ebenfalls absichtlich - es zeigt mir, dass es sich um eine "Gruppe von vielen c's" handelt.

269voto

Jamiec Punkte 127963

Gegeben eine Liste:

var list = new List()
{
    new Child()
        {School = "School1", FavoriteColor = "blue", Friend = "Bob", Name = "John"},
    new Child()
        {School = "School2", FavoriteColor = "blue", Friend = "Bob", Name = "Pete"},
    new Child()
        {School = "School1", FavoriteColor = "blue", Friend = "Bob", Name = "Fred"},
    new Child()
        {School = "School2", FavoriteColor = "blue", Friend = "Fred", Name = "Bob"},
};

Die Abfrage würde wie folgt aussehen:

var newList = list
    .GroupBy(x => new {x.School, x.Friend, x.FavoriteColor})
    .Select(y => new ConsolidatedChild()
        {
            FavoriteColor = y.Key.FavoriteColor,
            Friend = y.Key.Friend,
            School = y.Key.School,
            Children = y.ToList()
        }
    );

Testcode:

foreach(var item in newList)
{
    Console.WriteLine("Schule: {0} Lieblingsfarbe: {1} Freund: {2}", item.School,item.FavoriteColor,item.Friend);
    foreach(var child in item.Children)
    {
        Console.WriteLine("\t Name: {0}", child.Name);
    }
}

Ergebnis:

Schule: School1 Lieblingsfarbe: blue Freund: Bob
    Name: John
    Name: Fred
Schule: School2 Lieblingsfarbe: blue Freund: Bob
    Name: Pete
Schule: School2 Lieblingsfarbe: blue Freund: Fred
    Name: Bob

4 Stimmen

Für diejenigen unter uns, die die fließende Benutzeroberfläche bevorzugen. Eine winzige Beanstandung: Die Verwendung derselben Variablen "x" in beiden Func-Definitionen ist für neue Benutzer nicht sehr klar. Ich empfehle, diese zu ändern, um zu der oben genannten übereinstimmen, bei der "c" das Kind ist und "gcs" die gruppierten Kinder sind.

4 Stimmen

@jazmatician - Ich stimme Ihnen zu, dass die Wiederverwendung von x einige verwirren könnte, aber nicht bei der Wahl der Variablennamen. Ich werde es zu x und y ändern, um sie zu unterscheiden.

0 Stimmen

Die Variablennamen sind auch nicht meine Wahl. Tatsächlich habe ich beim Schreiben damit gekämpft herauszufinden, was "gcs" für den Autor bedeutet hat. Das Beste, was ich mir vorstellen konnte, war "Gruppe (von) Cs." Wie auch immer, ich habe es nur empfohlen, um es jemandem leicht zu machen, eine gedankliche Verbindung zwischen den beiden Syntaxen herzustellen. (Syntaces? Ich wette, Syntax ist eines dieser Wörter, das seinen eigenen Plural hat. Weil das Englisch ist, warum sollte "Syntax" den syntaktischen Regeln über Plurale unterliegen?)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X