2013-05-17 7 views
6

ich LINQ viele Beispiele verwendet haben, wie eine Liste in Unterliste teilen nach max Elemente in jeder Liste. Aber in diesem Fall bin ich daran interessiert, eine Sub-Liste mit Sizemb als Gewicht zu tauchen - mit einer maximalen Dateigröße von 9mb.LINQ: Split-Liste in Gruppen nach Gewicht/Größe

public class doc 
    { 
     public string file; 
     public int sizemb; 
    } 

    var list = new List<doc>() 
    { 
     new doc { file = "dok1", sizemb = 5 }, 
     new doc { file = "dok2", sizemb = 5 }, 
     new doc { file = "dok3", sizemb = 5 }, 
     new doc { file = "dok4", sizemb = 4 }, 
    }; 

    int maxTotalFileSize = 9; 

Die obige Liste sollte dann in 3 Listen unterteilt werden. Wenn "Dateien" mehr als 9 MB groß sind, sollten sie in einer eigenen Liste stehen.

Ich habe eine nicht LINQ-Version hier:

 var lists = new List<List<doc>>(); 
     foreach (var item in list) 
     { 
      //Try and place the document into a sub-list 
      var availableSlot = lists.FirstOrDefault(p => (p.Sum(x => x.sizemb) + item.sizemb) < maxGroupSize); 
      if (availableSlot == null) 
       lists.Add(new List<doc>() { item }); 
      else 
       availableSlot.Add(item); 
     } 
+0

, warum es drei Listen sein sollte, gibt es nur zwei eindeutige Werte –

+0

Sie wollen mit doc2 und Liste mit doc3 und DOC4 mit doc1, Liste Liste erreichen? –

+1

Was ist das erwartete Ergebnis? –

Antwort

7

könnten Sie diese Methode verwenden:

IEnumerable<IList<doc>> SplitDocumentList(IEnumerable<doc> allDocuments, int maxMB) 
{ 
    var lists = new List<IList<doc>>(); 
    var list = new List<doc>(); 
    foreach (doc document in allDocuments) 
    { 
     int totalMB = list.Sum(d => d.sizemb) + document.sizemb; 
     if (totalMB > maxMB) 
     { 
      lists.Add(list); 
      list = new List<doc>(); 
     } 
     list.Add(document); 
    } 
    if (list.Count > 0) 
     lists.Add(list); 
    return lists; 
} 

Hier eine Demo: http://ideone.com/OkXw7C

dok1 
dok2 
dok3,dok4 
+0

+1 für die Lesbarkeit, könnte der Sum-Operator durch eine lokale Summenvariable im Falle von Leistungsproblem (warum haben Sie Ihre erste Antwort löschen?) –

+0

Ich bin beeindruckt von dieser schnellen Antwort, aber die oben genannten verwendet nicht wirklich LINQ – bluee

+0

@ vc74: Ich habe es vorübergehend gelöscht, da es einen Fehler gab. Ich habe die '... lists.Add (list);' nach der Schleife hinzugefügt. –

0

Sie die Aggregate-Funktion, das zu tun verwenden, wird die Gruppe von nur funktionieren, wenn die Werte nicht auf der Grundlage einer beliebigen Zustand bei einem Vergleich eine starten neue Gruppe

list.Aggregate(new List<List<doc>>(), (acc,d) => { 
      if(acc.last().Sum(x => x.sizemb) + d.sizemb > 9) { 
       acc.Add(new List<doc>()); 
      } 
      acc.last().Add(d); 
      return acc; 
    } 
) 
+1

Ich kann dies nicht zum kompilieren .. – bluee

+0

@bluee, wenn Sie mir sagen, der Fehler, den ich bin Sicher, ich kann das Problem beheben, aber die allgemeine Idee wäre die gleiche. Ich denke, es war einfach die '}' anstelle von einem ')' am Ende –

Verwandte Themen