假设我有一个数字列表,就像这样:
有没有使用Linq表达这个的方法?
[3, 3, 1, 2, 3, 2]
我希望你能帮我将它们分成若干个组,并使得每个组的总和小于或等于五。正确答案是:
[3], [3, 1], [2,3], [2]
有没有使用Linq表达这个的方法?
[3, 3, 1, 2, 3, 2]
我希望你能帮我将它们分成若干个组,并使得每个组的总和小于或等于五。正确答案是:
[3], [3, 1], [2,3], [2]
var results = xs.Aggregate<int, List<List<int>>>(
new List<List<int>> { new List<int>() },
(a, n) =>
{
if (a.Last().Sum() + n > 5)
{
a.Add(new List<int> { n });
}
else
{
a.Last().Add(n);
}
return a;
});
var xs = new [] { 3, 3, 1, 2, 3, 2, };
不知道这是否与您想要的接近,但让我们试一试吧。
List<int> l = new List<int> { 3, 3, 1, 2, 3, 2 };
int[] index = {0};
var s = l.Select((k, i) =>
{
if (i < index[0])
return null;
int total = 0;
return l.Skip(index[0]).TakeWhile(x =>
{
total += x;
if (total <= 5)
index[0]++;
return total <= 5;
});
}).Where(x => x != null);
foreach (IEnumerable<int> e in s)
{
foreach (int i in e)
{
Console.Write("{0},", i);
}
Console.WriteLine();
}
我的推理如下:
我尝试使用int index = 0;
最初,但Resharper抱怨访问修改的闭包并建议将其更改为int[] index = {0};
public static class Extensions
{
public static IEnumerable<IEnumerable<int>> GroupsLessThan(this IEnumerable<int> source, int target)
{
var list = new List<int>();
var runningCount = 0;
foreach (var element in source)
{
if (runningCount + element < target)
{
list.Add(element);
runningCount += element;
}
else
{
yield return list;
runningCount = element;
list = new List<int>{element};
}
}
if (list.Count > 0)
{
yield return list;
}
}
}
使用方法如下:
var array = new int[] { 3, 3, 1, 2, 3, 2 };
var list = array.GroupsLessThan(6).ToList();