2012-12-20 8 views
5

Ho una domanda simile a yesterday's question.
Ho questo oggetto Lista <[]>Raggruppa una lista <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 }); 

ho bisogno di produrre Lista < oggetto [] > di tenere presente:

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

In altre parole, ho bisogno di gruppo Olst da e 2o elementi di ciascun oggetto [] e somma 3o e 4o.
Potrei usare un ciclo for, ma speravo che qualcuno potesse aiutarmi a usare espressioni lambda e/o linq per realizzare questo.

+9

Perché stai usando un ' oggetto [] 'per trattenere le stringhe. Se sai che sono stringhe, usa una 'stringa []'. O, meglio ancora, crea un nuovo tipo con due proprietà significative per rappresentare questi due valori. – Servy

+0

@Servy - questo è solo un esempio. – Administrateur

+0

Se sai che stai lavorando con una coppia, piuttosto che con un numero sconosciuto, allora una Tupla <,> o KeyValuePair <,> potrebbe essere idiomatica. –

risposta

4

Hai bisogno di gruppo da parte di un tipo anonimo, poi sommare la terza e la quarta colonna:

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(); 

Qualcosa di simile?

+1

vuoi selezionare 'g.First()'. – Servy

+0

sì, grazie per la correzione. –

0

Come suggerito nei commenti, vorrei andare con Tuple e magari utilizzare HashSet, poiché verrà aggiunto solo se l'elemento non esiste (anche, è veloce). Se aggiungi elementi a hashset, non è necessario selezionare distinti finché il tuo tipo fornisce i metodi Equals e GetHashCode necessari.
Qualcosa di simile a questo:

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")); 

Se avete bisogno è possibile convertirlo per elencare. Ecco un esempio:

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

stamperà

AA1 X 
AA2 Y 
+0

Se i tipi di oggetti non sono tutti uguali e se non c'è un numero consistente di elementi (l'OP si rifiuta di confermare o negare una di queste asserzioni), allora questa soluzione non funzionerà. – Servy

+0

@Servy, Sì, ne sono consapevole. Solo una possibile soluzione. Questo è tutto ciò che posso dedurre dalla domanda OP a questo punto, sfortunatamente. Grazie per averlo fatto notare però. – RAS