Laden...

[erledigt] Linq-Artikel auf Wikipedia für "Group" fehlerhaft

Erstellt von ErfinderDesRades vor 8 Jahren Letzter Beitrag vor 8 Jahren 2.012 Views
ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 8 Jahren
[erledigt] Linq-Artikel auf Wikipedia für "Group" fehlerhaft

Hi! Ich studiere grade Wikipedia - Linq: LINQ

Alles ok, ausser was da zu Group steht. Dieses meine Testklasse:


   public class Employee {
      public string Name; public int Department; public int Age;
   }

Und wenn ich nun den Wiki-Code bei mir einkopiere, kompiliert das nicht:


      public void Test() {
         var Employees = new List<Employee>();
         var groupedEmployees = 
            from e in Employees
            group e by e.Department 
            group e by e.Age
            select e;

         var groupedEmployees2 = 
            from e in Employees
            group e by new { e.Department , e.Age } 
            select e;

Oder hab ich iwas falsch übernommen von denen?
In meinen Versuchen scheint beim Groupen ein into-Abschnitt obligatorisch.
Und die 2-dimensionale Gruppierung (groupedEmployees) bekomme ich ühaupt nicht gebacken 🙁

(naja - kaum hingeschrieben finde ich doch was):


         var groupedEmployees = 
            from e in Employees
            group e by e.Department into x
            from y in x group y by y.Age into z
            select z;

Edit: (und getestet, und es ist Blödsinn)

Der frühe Apfel fängt den Wurm.

849 Beiträge seit 2006
vor 8 Jahren

Ja, der Artikel scheint fehlerhaft..

ich habe glaube auch noch nie ein group by ohne into gesehen. (Obwohl ich die ()=> schreibweise bevorzuge)

also dein 2. Beispiel müsste dann so aussehen:


from e in Employees
               group e by new { e.Age,e.Department} into f
               select f

Das erste geht imho so überhaupt nicht, weil das e nach dem group schon "out of scope" ist, und in f ist schon die fertige Gruppe. Darin könnte man nur noch soetwas wie


    var groupedEmployees =
               (from e in Employees
               group e by new { e.Age,e.Department} into f
               group f by f.Count() into g
               select g).ToList();

machen.

Gruß

3.003 Beiträge seit 2006
vor 8 Jahren

Wunderschönes Beispiel, wieso Wikipedia...egal, anderes Thema.

Ich komme mit der ausgeschriebenen Syntax nicht gut klar, aber der erste sollte so was hier sein:


var groupedEmployees = employees.GroupBy(p => p.Department, p => p, (p, d) => d.GroupBy(q => q.Age));

var groupedEmployees2 = employees.GroupBy(p => new { p.Age, p.Department });


Wenn ich richtig verstanden habe, was der WP-Autor uns sagen wollte. Wobei das zweite Beispiel viel mehr Sinn ergibt, wenn man das hier draus macht:


var groupedEmployees2 = employees.GroupBy(p => new { p.Age, p.Department }, p => p.Name);

Aber selbst dann ist das Beispiel ein ziemlich schlechtes.

LaTino
EDIT: erstes GroupBy-Beispiel durch andere Überladung von GroupBy-Extension ersetzt
EDIT: mglw. schwierig nachzuvollziehen, daher:


var groupedEmployees = employees
    .GroupBy(
        p => p.Department, //erstes Argument, anhand welcher Dimension aggregiert werden soll.
        p => p, //transformation der Elemente bei der Auswahl, hier: keine
        (p, d) => d.GroupBy(q => q.Age) //Anweisung nach dem Gruppieren, hier: innerhalb der Gruppe nochmals gruppieren, diesmal nach Alter.
    );

Hoffe, das hilft ein wenig.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 8 Jahren

(Obwohl ich die ()=> schreibweise bevorzuge) Jo, dem neige ich jetzt auch zu, wenn ich so Vergleiche ziehe:


         { 
            var result2 = from p in products group p by p.CategoryId into g select g;
            var result3 = products.GroupBy(p => p.CategoryId);
         }

Die Linq-Syntax hat 11 Wort-Zwischenräume (also textuelle Einheiten zu beachten), die Lambda-Schreibe nur 2 - oder mw. 4, wenn man Klammern auch als Text-Trenner auffasst.

Aber ich glaub ich werd in Zukunft eh kaum mehr groupen, denn grad habich .ToLookup entdeckt:


         { // ToLookup() als Alternative zum GroupBy: Ein Lookup ist gleichzeitig auch ein Dictionary der Groups
            var result = products.ToLookup(p => p.CategoryId);
            var x = result[4];
            var result2 = from p in products group p by p.CategoryId into g select g;
            var result3 = products.GroupBy(p => p.CategoryId);
            var arr = result.ToArray();
            arr  = result2.ToArray();
            arr  = result3.ToArray();
         }

syntax-Identisch mit GroupBy(), und auch die Ergebnismenge ist dieselbe (sieht man daran, dass aller dreier Datentyp nach ToArray an dieselbe variable zugewiesen werden kann.
Ein Lookup ist aber zusätzlich gleichzeitig auch sowas wie ein Dictionary, wo man die Groups also nicht nur enumerieren kann, sondern auch per Key zugreifen.
Ein Unterschied besteht ausserdem darin, dass Lookup bereits evaluiert ist - ist mir meist sogar erwünscht.


Jo das Wiki nicht wirklich eine Coder-Resource ist, sah und seh ich auch so. Aber die anderen Beschreibungen
(v.a. Join, Group Join, Left Outer Join, inkl DefaultIfEmpty) fand ich sehr gut und auch bestätigt. Das hat mich denken machen, die wüssten, wovon sie reden 😉

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 8 Jahren

Zukunft eh kaum mehr groupen, denn grad habich .ToLookup entdeckt:
[..]
Ein Unterschied besteht ausserdem darin, dass Lookup bereits evaluiert ist - ist mir meist sogar erwünscht.

Zweischneidiges Schwert 😃. Die Nicht-Evaluierung hat einige Vorteile, weil bei Verkettungen der Gesamtausdruck optimiert ausgewertet wird/werden kann. Je nach Linq-Provider kann das sehr viel schneller und besser sein als das, was man per Hand erreicht, wenn man direkt auf den Daten arbeitet. Debuggen ist schwieriger, meiner Meinung nach. Dafür erzwingt das Arbeiten auf nicht-evaluierten Daten das Arbeiten MIT den Daten statt AUF* ihnen, was eine Umgewöhnung ist, aber das Leben leichter machen kann.

LaTino

  • wieder schwer verständlich.

var daten = datenbasis.Where(p => p.Eigenschaft == 5).ToList();
var result = new List<DatenEintrag>();
for(int i = 0; i < daten.Count; i++) //arbeiten AUF den Daten.
{
    result.Add(new DatenEintrag(daten[i]));
}

var result2 = datenbasis.Where(p => p.Eigenschaft == 5).Select(p => new DatenEintrag(p)); //...und MIT den Daten. Noch wurde hier kein einziges Objekt erstellt.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

ErfinderDesRades Themenstarter:in
5.299 Beiträge seit 2008
vor 8 Jahren

Jo, da kann man einiges zu sagen, wann was günstiger ist.

Bei mir ist häufiger vor-evaluierung angezeigt, weil ich meine Listen leicht überwiegend mehrfach benutze.
Aber ist eh zu 99% irrelevant, denn nur ganz ganz selten habich mit Datenmengen von auch nur über 100 Stück zu tun - das wäre nichtmal schlimm, es mehrfach zu evaluieren.

Der frühe Apfel fängt den Wurm.