You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#的LINQ是否存在等价于F# Seq.scan的方法?

答案

.NET 6及更高版本的System.Linq中已经提供了与F# Seq.scan完全等价的Enumerable.Scan方法,包含两种重载:

1. 带初始值的重载(对应Seq.scan)

需要传入初始聚合值,返回包括初始值在内的每一步聚合结果:

using System.Linq;

var numbers = new[] { 1, 2, 3, 4 };
// 以0为初始值,计算累加的每一步
var cumulativeSums = numbers.Scan(0, (accumulated, current) => accumulated + current);
// 输出结果:0, 1, 3, 6, 10
foreach (var sum in cumulativeSums)
{
    Console.WriteLine(sum);
}

2. 无初始值的重载(类似Seq.reduce的扫描版本)

无需初始值,以序列的第一个元素作为初始聚合值,返回后续每一步的聚合结果:

using System.Linq;

var numbers = new[] { 1, 2, 3, 4 };
// 以第一个元素为初始值,计算累加的每一步
var cumulativeSums = numbers.Scan((accumulated, current) => accumulated + current);
// 输出结果:1, 3, 6, 10
foreach (var sum in cumulativeSums)
{
    Console.WriteLine(sum);
}

如果使用.NET 5及更早版本

核心类库没有内置Scan方法,你可以自行实现扩展方法:

带初始值的扩展方法

public static class EnumerableExtensions
{
    public static IEnumerable<TResult> Scan<TSource, TResult>(this IEnumerable<TSource> source, TResult seed, Func<TResult, TSource, TResult> accumulator)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (accumulator == null) throw new ArgumentNullException(nameof(accumulator));

        yield return seed;
        var current = seed;
        foreach (var item in source)
        {
            current = accumulator(current, item);
            yield return current;
        }
    }
}

无初始值的扩展方法

public static class EnumerableExtensions
{
    public static IEnumerable<TSource> Scan<TSource>(this IEnumerable<TSource> source, Func<TSource, TSource, TSource> accumulator)
    {
        if (source == null) throw new ArgumentNullException(nameof(source));
        if (accumulator == null) throw new ArgumentNullException(nameof(accumulator));

        using var enumerator = source.GetEnumerator();
        if (!enumerator.MoveNext())
            yield break;

        var current = enumerator.Current;
        yield return current;
        while (enumerator.MoveNext())
        {
            current = accumulator(current, enumerator.Current);
            yield return current;
        }
    }
}

你也可以选择使用LanguageExt库中的Scan方法,但如果优先使用核心类库,以上自行实现的方式完全满足需求。

内容的提问来源于stack exchange,提问作者Lyndon Gingerich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:45:13