C#是否有一个等同于F#的Seq.scan
的LINQ--像fold
一样,但在每一步都存储聚合值?(像reduce
这样不需要启动状态的LINQ至少也可以).
如果不存在,我可以通过编写自己的或使用LanguageExt的方法来解决它的缺失,但我更喜欢在可能的情况下使用核心库.
C#是否有一个等同于F#的Seq.scan
的LINQ--像fold
一样,但在每一步都存储聚合值?(像reduce
这样不需要启动状态的LINQ至少也可以).
如果不存在,我可以通过编写自己的或使用LanguageExt的方法来解决它的缺失,但我更喜欢在可能的情况下使用核心库.
C#没有与F#的Seq.scan
方法等价的直接LINQ.
您可以使用LINQ聚合器方法模拟此功能,方法是将集合作为种子值传递并对前面的累加执行查找:
public class Data
{
public int Count { get; set; }
}
var data = new List<Data>
{
new Data { Count = 1 },
new Data { Count = 2 },
new Data { Count = 1 },
new Data { Count = 5 },
new Data { Count = 3 }
};
var accumulatedValues = data.Aggregate(new List<int>(), (current, nextValue) =>
{
var lastValue = current.Count > 0 ? current[current.Count - 1] : 0;
var updatedValue = lastValue + nextValue.Count;
current.Add(updatedValue);
return current;
});
此外,创建自己的扩展方法模仿Aggregate
函数,但返回所有累加步骤的列表,而不是返回单个值,这是相对简单的.
public static class Extensions
{
public static IEnumerable<TAccumulate> Accumulate<TSource, TAccumulate>(
this IEnumerable<TSource> source,
TAccumulate seed,
Func<TAccumulate, TSource, TAccumulate> accumulat或)
{
var accumulation = new List<TAccumulate>();
var current = seed;
f或each (var item in source)
{
current = accumulat或(current, item);
accumulation.Add(current);
}
return accumulation;
}
}
这对原始值集合和对象集合都很有效:
var firstAccumulation =
Enumerable.Range(1, 10).Accumulate(0, (acc, newValue) => acc + newValue);
或
public class Data
{
public int Count { get; set; }
}
var data = new List<Data>
{
new Data { Count = 1 },
new Data { Count = 2 },
new Data { Count = 1 },
new Data { Count = 5 },
new Data { Count = 3 }
};
var secondAccumulation = data.Accumulate(0, (acc, newValue) => acc + newValue.Count);