是否有标准的LINQ运算符,通过展望自己的元素将IEnumerable <t>转换为另一个

时间:2016-04-24 18:38:06

标签: c# linq

是否有一个标准的linq运算符可以帮助我生成一个IEnumerable<int>的算术进展,而不是自己迭代这些元素?

例如

int[] numbers = { 7, 12, 14, 8 };

// I would like an IEnumerable<int>
// whose values are:
IEnumerable<int> result = ... // { 19, 33, 41 }

我想懒惰地在一个查询中执行此操作,即无需编写foreach循环。

我正在寻找,但无法从标准组合中找到任何组合器。

我怀疑我可以使用Select加上Aggregate的重载之一可能会帮助我这样做,但我仍在尝试自己并且不确定。我认为发布这个问题并让其他人跟我比赛会很有趣吗?

更新 我改变了我的问题。我认为我想要的输出是:

{ 7 ,19, 33, 41}

Jacob用代码正确回答:

var accumulator = 0;
return numbers.Select(n => accumulator += n);

但我在想,如果我想让输出只是

{ 19, 33, 41 }

我将如何&#34;展望未来&#34;进入可枚举的相同来源?

2 个答案:

答案 0 :(得分:2)

此操作通常称为扫描。没有内置运算符(尽管F#将其定义为Seq.scan,但您可以自己定义它:

    public static IEnumerable<TAcc> Scan<T, TAcc>(this IEnumerable<T> seq, Func<TAcc, T, TAcc> f, TAcc initial)
    {
        TAcc current = initial;
        yield return current;
        foreach(T item in seq)
        {
            current = f(current, item);
            yield return current;
        }
    }

扫描通常会产生您不需要的初始值,因此您可以Skip

int[] numbers = { 7, 12, 14, 8 };
var result = numbers.Scan((acc, x) => acc + y, 0).Skip(1);

答案 1 :(得分:1)

我不知道任何内置运算符可以做到这一点,但只需通过常规Select即可轻松实现:

var accumulator = 0;
return numbers.Select(n => accumulator += n);