public class InvestorMailing
{
public string To { get; set; }
public IEnumerable<string> Attachments { get; set; }
public int AttachmentCount { get; set; }
public long AttachmentSize { get; set; }
}
i have an IList<InvestorMailing> mailingList
. if the attachment size is greater than x, then i need to split my object into chunks. is there an easy linq-y way to do this?
我有一个投资邮件列表。如果附件大小大于x,则需要将对象分割成块。有没有一种简单的linq-y方法?
Edited:
编辑:
this is how i'm generating my mailings:
这就是我如何生成我的邮件:
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();
3 个解决方案
#1
1
It should be pretty simple to do it with a standard method. Consider this example:
用标准方法来做应该很简单。考虑一下这个例子:
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));
}
Edit
编辑
I worked on it a bit and produced a LINQ version. It doesn't really save much code in this case, but it's a start.
我做了一点工作,并制作了一个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));
}
#2
1
Here's a way to do it using some LINQ to find a chunk that has enough space left to add the attachment:
这里有一种方法,使用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 });
}
}
The result is stored in chunks
.
结果以块的形式存储。
#3
0
Yes:
是的:
var highs = mailingList.Where(i => i.AttachmentSize > 10000).ToList();
var lows = mailingList.Where(i => i.AttachmentSize <= 10000).ToList();
How do you need to break them apart aside from this?
你要怎么把它们分开呢?
HTH.
HTH。
#1
1
It should be pretty simple to do it with a standard method. Consider this example:
用标准方法来做应该很简单。考虑一下这个例子:
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));
}
Edit
编辑
I worked on it a bit and produced a LINQ version. It doesn't really save much code in this case, but it's a start.
我做了一点工作,并制作了一个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));
}
#2
1
Here's a way to do it using some LINQ to find a chunk that has enough space left to add the attachment:
这里有一种方法,使用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 });
}
}
The result is stored in chunks
.
结果以块的形式存储。
#3
0
Yes:
是的:
var highs = mailingList.Where(i => i.AttachmentSize > 10000).ToList();
var lows = mailingList.Where(i => i.AttachmentSize <= 10000).ToList();
How do you need to break them apart aside from this?
你要怎么把它们分开呢?
HTH.
HTH。