我有一个有96个值的集合。我想总结4个连续索引的值。我怎么能用Linq做到这一点?
实施例
collection = {100, 101, 200, 150, 103, 105, 100, 104, .........., 20, 40, 60, 80};
(100, 101, 200, 150;)
之和,然后(103, 105, 100, 104;)
的总和...然后(20, 40, 60, 80;)
的总和这意味着现在我的新集合将有24个值。
如何使用Linq执行此操作?
答案 0 :(得分:11)
我们可以根据给定的批量大小将此实用程序功能从Batch
项开始:
public static IEnumerable<IEnumerable<T>> Batch<T>(this IEnumerable<T> source, int batchSize)
{
List<T> buffer = new List<T>(batchSize);
foreach (T item in source)
{
buffer.Add(item);
if (buffer.Count >= batchSize)
{
yield return buffer;
buffer = new List<T>(batchSize);
}
}
if (buffer.Count > 0)
{
yield return buffer;
}
}
之后它就像:
一样简单var query = data.Batch(4)
.Select(batch => batch.Sum());
答案 1 :(得分:4)
您可以按index/4
分组以获得您的总和,如下所示:
var res = collection
.Select((v,i) => new {v, i})
.GroupBy(p => p.i / 4)
.Select(g => g.Sum(p.v));
答案 2 :(得分:3)
您可以从索引,组中计算组索引,并从每组中的值中获取总和:
var sums = collection
.Select((n, i) => new { Group = i / 4, Value = n })
.GroupBy(x => x.Group)
.Select(g => g.Sum(y => y.Value));
答案 3 :(得分:1)
您需要一种新的扩展方法Partition
:
public static IEnumerable<IEnumerable<T>> Partition<T>(
this IEnumerable<T> source, int partitionSize)
{
var counter = 0;
var result = new T[partitionSize];
foreach(var item in source)
{
result[counter] = item;
++counter;
if(counter >= partitionSize)
{
yield return result;
counter = 0;
result = new T[partitionSize];
}
}
if(counter != 0)
yield return result.Take(counter);
}
用法是:
collection.Partition(4).Select(x => x.Sum())
这是Servy发布的Batch
方法的替代方法。
答案 4 :(得分:1)
首先,设置一种按索引对集合进行分组的方法。在这种情况下,我选择使用整数除法来生成0-3组0,4-7组1等元素。
接下来,将您的元素分组到需要求和的不同集合(通过分组键)。
最后,选择属于每个组的元素总和。
values.Select((x, i) => new { GroupingKey = i/4, Value = x })
.GroupBy(x => x.GroupingKey)
.Select(x => new { Group = x.Key, Sum = x.Sum() });
答案 5 :(得分:0)
这样做:
static IEnumerable<int> BatchSum(int batchSize, IEnumerable<int> collection)
{
var batch = collection.Take(batchSize).ToList();
if (batch.Count == 0) yield break;
yield return batch.Sum();
var rest = collection.Skip(batchSize);
foreach (var sum in BatchSum(batchSize, rest)) yield return sum;
}
使用它:
var collection = new[] { 100, 101, 200, 150, 103, 105, 100, 104, 20, 40, 60, 80, 11, 13 };
foreach (var sum in BatchSum(4, collection)) Show(sum);
输出结果为:
551
412
200
24
如您所见,您的收藏长度不应是batchSize
的因素。