This should be fairly easy to do with the 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 a bit on this and released the LINQ version. In this case, this does not save much code, but this is the beginning.
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));
}
source
share