2010-04-22 2 views
3
public class InvestorMailing 
{ 
    public string To { get; set; } 

    public IEnumerable<string> Attachments { get; set; } 

    public int AttachmentCount { get; set; } 

    public long AttachmentSize { get; set; } 
} 

У меня есть IList<InvestorMailing> mailingList. если размер вложения больше x, тогда мне нужно разделить мой объект на куски. есть ли простой способ linq-y сделать это?Как разбить объект на куски на основе какого-либо свойства?

Отредактировано:

это, как я буду генерировать мои рассылки:

 var groupedMailings = mailingList.GroupBy(g => g.GroupBy); 

     var investorMailings = groupedMailings.Select(
      g => new DistinctInvestorMailing 
      { 
       Id = g.Select(x => x.Id).FirstOrDefault(), 
       To = g.Key.Trim(), 
       From = g.Select(x => x.From).FirstOrDefault(), 
       FromName = g.Select(x => x.FromName).FirstOrDefault(), 
       Bcc = g.Select(x => x.Bcc).FirstOrDefault(), 
       DeliveryCode = g.Select(x => x.DeliveryCode).FirstOrDefault(), 
       Subject = g.Select(x => x.Subject).FirstOrDefault(), 
       Body = g.Select(x => x.Body).FirstOrDefault(), 
       CommentsOnStatus = g.Select(x => x.CommentsOnStatus).FirstOrDefault(), 
       Attachments = g.Select(x => x.AttachmentPath), 
       AttachmentCount = g.Select(x => x.AttachmentPath).Count(), 
       AttachmentSize = g.Sum(x => x.AttachmentSize), 
       MailType = g.Select(x => x.MessageType).FirstOrDefault() 
      } 
     ).ToList(); 
+0

Что вы хотите разбить? Список InvestorMailings или Приложений индивидуального инвестора? – dtb

+0

InventorMailing - это объект, каждый из которых имеет собственное свойство AttachmentCount. Когда вы хотите разбить? Вы хотите разбить, даже если один элемент в списке больше, чем x? – azamsharp

+0

Почти так же, как http://stackoverflow.com/questions/2678008/how-to-split-linq-grouping –

ответ

1

Это должно быть довольно просто сделать это с помощью стандартного метода. Рассмотрим следующий пример:

class Foo 
{ 
    public Foo(int weight) { Weight = weight; } 
    public int Weight { get; set; } 
} 

...

IEnumerable<IList<Foo>> GroupFoosByWeight(IList<Foo> foos, int weightLimit) 
{ 
    List<Foo> list = new List<Foo>(); 
    int sumOfWeight = 0; 

    foreach (Foo foo in foos) 
    { 
     if (sumOfWeight + foo.Weight > weightLimit) 
     { 
      yield return list; 
      sumOfWeight = 0; 
      list.Clear(); 
     } 

     list.Add(foo); 
     sumOfWeight += foo.Weight; 
    } 

    if (list.Count > 0) 
     yield return list; 
} 

...

List<Foo> foos = new List<Foo>() 
{ 
    new Foo(15), new Foo(32), new Foo(14), new Foo(19), new Foo(27) 
}; 

foreach (IList<Foo> list in GroupFoosByWeight(foos, 35)) 
{ 
    Console.WriteLine("{0}\t{1}", list.Count, list.Sum(f => f.Weight)); 
} 

Редактировать

Я работал над ним немного и подготовил версию LINQ. В этом случае это не очень экономит код, но это начало.

int weightLimit = 35; 
int fooGroup = 0; 
int totalWeight = 0; 

Func<Foo, int> groupIncrementer = f => 
{ 
    if (totalWeight + f.Weight > weightLimit) 
    { 
     fooGroup++; 
     totalWeight = 0; 
    } 

    totalWeight += f.Weight; 

    return fooGroup; 
}; 

var query = from foo in foos 
      group foo by new { Group = groupIncrementer(foo) } 
       into g 
       select g.AsEnumerable(); 

foreach (IList<Foo> list in query) 
{ 
    Console.WriteLine("{0}\t{1}", list.Count, list.Sum(f => f.Weight)); 
} 
+0

это сработало - спасибо – CurlyFro

0

Да:

var highs = mailingList.Where(i => i.AttachmentSize > 10000).ToList(); 
var lows = mailingList.Where(i => i.AttachmentSize <= 10000).ToList(); 

Как вы должны разорвать их на части в стороне от этого?

HTH.

+0

Я * думаю * он хочет обрабатывать эти вещи партиями. Поэтому, как только он превысит определенный порог, выполните действие и продолжите. Так что это не индивидуальный размер, а коллектив. –

1

Вот способ сделать это с помощью некоторых LINQ, чтобы найти кусок, который имеет достаточно свободного места, чтобы добавить вложение:

var chunks = new List<List<InvestorMailing>>(); 
int maxAttachmentsSize = 10; 

foreach (InvestorMailing mail in mailingList) 
{ 
    var chunkWithSpace = chunks 
     .Where(list => list.Sum(x => x.AttachmentSize) + 
         mail.AttachmentSize <= maxAttachmentsSize) 
     .FirstOrDefault(); 

    if (chunkWithSpace != null) 
    { 
     chunkWithSpace.Add(mail); 
    } else { 
     chunks.Add(new List<InvestorMailing> { mail }); 
    } 
} 

Результат сохраняется в chunks.

Смежные вопросы