2013-05-17 35 views
6

Tôi đã sử dụng LINQ làm cách nào để chia danh sách thành danh sách phụ theo các mục tối đa trong mỗi danh sách. Nhưng trong trường hợp này, tôi quan tâm đến việc lặn một danh sách phụ bằng cách sử dụng sizemb làm trọng lượng - có tổng số tệp tối đa cho mỗi danh sách 9mb.LINQ: Chia danh sách thành các nhóm theo trọng lượng/kích thước

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; 

Danh sách trên sẽ được chia thành 3 danh sách. Nếu bất kỳ 'tệp' nào lớn hơn 9mb, chúng phải nằm trong danh sách riêng của chúng.

tôi đã thực hiện một tổ chức phi LINQ-phiên bản ở đây:

 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

lý do tại sao nó phải được ba danh sách chỉ có hai giá trị độc đáo –

+0

Bạn muốn đạt được danh sách với doc1, danh sách với doc2 và danh sách với doc3 và doc4? –

+1

Kết quả mong đợi là gì ?? –

Trả lời

7

Bạn có thể sử dụng phương pháp này:

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; 
} 

Dưới đây là một bản demo: http://ideone.com/OkXw7C

dok1 
dok2 
dok3,dok4 
+0

+1 để dễ đọc, toán tử Sum có thể được thay thế bằng biến tổng cục bộ trong trường hợp vấn đề hiệu năng (tại sao bạn xóa câu trả lời ban đầu của mình?) –

+0

Tôi ấn tượng với phản hồi nhanh này, nhưng ở trên không thực sự sử dụng LINQ – bluee

+0

@ vc74: Tôi đã xóa nó tạm thời vì có lỗi. Tôi đã thêm '... lists.Add (list);' sau vòng lặp. –

0

Bạn có thể sử dụng chức năng tổng hợp để làm điều đó, nhóm bởi sẽ chỉ làm việc khi so sánh giá trị không dựa trên một điều kiện tùy ý khi nào bắt đầu một nhóm mới

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

Tôi không thể thực hiện việc này để biên dịch .. – bluee

+0

@bluee nếu bạn cho tôi biết lỗi chắc chắn tôi có thể khắc phục vấn đề nhưng ý tưởng chung sẽ giống nhau. Tôi đoán nó đơn giản là '}' thay vì ')' vào cuối –

Các vấn đề liên quan