LINQで累積和を計算する方法

この記事は公開から3年以上経過しています。

LINQで区間の和(累積和)を計算する方法。

つまり入力要素が{1,2,…,10}のような場合に

0+1=1
1+2=3
3+3=6
6+4=10
10+5=15
15+6=21
21+7=28
28+8=36
36+9=45
45+10=55

の右辺値を取得する方法となります。

サンプルソースコード

もっと良い方法があるのかもしれませんが、以下のような拡張メソッドで…。
例はC#ですが、VB.NETなどでも同様に対応が可能です。
dynamic型を利用しているため、.NETFramework4.0以降が必要です(Microsoft.CSharpへの参照をお忘れなく)。

C#

using System;
using System.Collections.Generic;
using System.Linq;

namespace LinqTest210109
{
    internal class Program
    {
        private static void Main()
        {
            var result = Enumerable.Range(1, 10).Select(s => (short)s).CumulativeSum();
            foreach (var s in result)
                Console.WriteLine(s);
            Console.ReadKey();
        }
    }

    internal static class Utils
    {
        public static IEnumerable<T> CumulativeSum<T>(this IEnumerable<T> values)
        {
            dynamic sum = default(T);
            foreach (T value in values)
                yield return (T)(sum += value);
        }
    }
}

入力データの数値型が決まっている場合は、明示的に型指定したほうがパフォーマンスが向上します。
ただし、LINQのようなIEnumerableによる反復処理は若干コストが高いため、高パフォーマンスが求められる場合は、unsafe配列などを使い一気に計算したほうが良いかもしれません。

以上です。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする