2012-12-20 7 views
5

Ich habe eine Frage, die auf yesterday's question ähnlich ist.
Ich habe diese Liste < Objekt [] >Gruppe eine Liste <object[]>

List<object[]> olst = new List<object[]>(); 

olst.Add(new object[] { "AA1", "X", 1, 3.50 }); 
olst.Add(new object[] { "AA2", "Y", 2, 5.20 }); 
olst.Add(new object[] { "AA2", "Y", 1, 3.50 }); 
olst.Add(new object[] { "AA1", "X", 1, 3.20 }); 
olst.Add(new object[] { "AA1", "Y", 2, 5.30 }); 

I Liste < Objekt [] > halten diese produzieren müssen:

"AA1", "X", 2, 6.70 
"AA2", "Y", 3, 8.70 
"AA1", "Y", 2, 5.30 

Mit anderen Worten, ich brauche zu Gruppe olst durch die 1. und 2. Elemente jedes Objekts [] und Summe 3. und 4..
Ich könnte eine for-Schleife verwenden, aber ich hatte gehofft, jemand könnte mir helfen, Lambda-Ausdrücke und/oder linq verwenden, um dies zu erreichen.

+9

Warum verwenden Sie ein ' object [] 'um an Strings zu halten. Wenn Sie wissen, dass es sich um Strings handelt, verwenden Sie eine 'string []'. Oder, noch besser, erstellen Sie einen neuen Typ mit zwei sinnvollen Eigenschaften, um diese beiden Werte darzustellen. – Servy

+0

@Servy - das ist nur ein Beispiel. – Administrateur

+0

Wenn Sie wissen, dass Sie mit einem Paar arbeiten, anstatt mit einer unbekannten Zahl, dann einem Tuple <,> oder KeyValuePair <,> könnte idiomatische sein. –

Antwort

4

Sie zu einer Gruppe von einem anonymen Typ benötigen, dann die dritte und vierte Spalte Summe:

List<object[]> grouped = olst 
    .GroupBy(o => new { Prop1 = o[0].ToString(), Prop2 = o[1].ToString() }) 
    .Select(o => new object[] 
    { 
     o.Key.Prop1, 
     o.Key.Prop2, 
     o.Sum(x => (int)x[2]), 
     o.Sum(x => (double)x[3]) 
    }) 
    .ToList(); 
6
List<object[]> olst = new List<object[]>(); 

      olst.Add(new object[] { "AA1", "X" }); 
      olst.Add(new object[] { "AA2", "Y" }); 
      olst.Add(new object[] { "AA2", "Y" }); 
      olst.Add(new object[] { "AA1", "X" }); 
      olst.Add(new object[] { "AA1", "Y" }); 

      var result = from ol in olst 
         group ol by new {p1 = ol[0], p2 = ol[1]} 
         into g 
         select g.First(); 

So ähnlich?

+1

möchten Sie 'g.First()' auswählen. – Servy

+0

ja, danke für die Korrektur. –

0

Wie in den Kommentaren vorgeschlagen, würde ich mit Tuple gehen und vielleicht HashSet stattdessen verwenden, da es nur anhängen wird, wenn Element nicht existiert (auch, es ist schnell). Wenn Sie Elemente zu hashset hinzufügen, müssen Sie distinct nicht auswählen, solange Ihr Typ die erforderlichen Equals- und GetHashCode-Methoden bereitstellt.
Etwas wie folgt aus:

var olst = new HashSet<Tuple<string,string>>(); 
      olst.Add(Tuple.Create("AA1", "X")); 
      olst.Add(Tuple.Create("AA1", "X")); 
      olst.Add(Tuple.Create("AA2", "Y")); 
      olst.Add(Tuple.Create("AA2", "Y")); 

Wenn Sie benötigen können Sie es konvertieren aufzulisten. Hier ein Beispiel:

olst.ToList().ForEach(x=> Console.WriteLine(x.Item1 + " " + x.Item2)); 

Wird drucken

AA1 X 
AA2 Y 
+0

Wenn die Typen der Objekte nicht alle gleich sind und es keine konsistente Anzahl von Elementen gibt (das OP weigert sich, eine dieser Behauptungen zu bestätigen oder abzulehnen), dann wird diese Lösung nicht funktionieren. – Servy

+0

@Servy, Ja, mir ist das bekannt. Nur eine mögliche Lösung. Das ist alles, was ich aus der OP-Frage an dieser Stelle leider ableiten kann. Danke, dass du es aufgezeigt hast. – RAS

Verwandte Themen