使用 Linq 按索引求和
本文关键字:求和 索引 Linq 使用 | 更新日期: 2023-09-27 18:17:51
我有一个有 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 执行此操作?
我们可以从这个实用程序函数开始,根据给定的批量大小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());
您可以
按index/4
分组以获得总和,如下所示:
var res = collection
.Select((v,i) => new {v, i})
.GroupBy(p => p.i / 4)
.Select(g => g.Sum(p.v));
您可以从索引中计算组索引,并在此基础上进行分组,并从每个组中的值中获取总和:
var sums = collection
.Select((n, i) => new { Group = i / 4, Value = n })
.GroupBy(x => x.Group)
.Select(g => g.Sum(y => y.Value));
您需要一个新的扩展方法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
方法的另一种方法。
首先,找到一种方法来按索引对集合进行分组。在这种情况下,我选择使用整数除法使元素 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() });
这样做
:
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
的因素。