LINQ:数値コレクション内の特定の数値だけを集計するには?[C#、VB].NET TIPS

Where拡張メソッドを使って、数値コレクションの要素の中で、特定の条件を満たす値だけを集計する方法を解説する。

» 2014年09月02日 13時13分 公開
.NET TIPS
Insider.NET

 

「.NET TIPS」のインデックス

連載目次

対象:.NET 3.5以降


 LINQを使って配列やコレクションに格納されている数値を集計するときに、特定の値を除外して合計したいことはないだろうか? ラムダ式を併用すればそれが可能だ。本稿ではその方法を説明する。

条件を満たす値だけを集計するには?

 例えば、配列やコレクションに格納されている数値の中から正の値だけを集計するには、Enumerableクラス(System.Linq名前空間)のWhere拡張メソッドを使い、引数として正の値を判定するラムダ式を与える(次のコード)*1

var nums = new int[] { 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, };
var sum = nums.Where(n => n > 0).Sum(); // 正の値だけを取り出して集計する
Console.WriteLine(sum); // →15

Dim nums = New Integer() {1, -1, 2, -2, 3, -3, 4, -4, 5, -5}
Dim sum = nums.Where(Function(n) n > 0).Sum() ' 正の値だけを取り出して集計する
Console.WriteLine(sum) ' →15

Where拡張メソッドを使って正の値だけを集計するコード例(上:C#、下:VB)
この他に、Enumerableクラスの拡張メソッドを使用するため、System.Linq名前空間のインポートが必要だ。
この例でWhere拡張メソッドの出力は、正でない値を除外した数値のコレクションになる。それを入力としてEnumerableクラスのSum拡張メソッドを呼び出すので、結果として正の値だけが集計される。

 あるいは、Sum拡張メソッドには、値を変換するラムダ式を引数として与えられるので、それを利用して次のように書くこともできる。

var nums = new int[] { 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, };
var sum = nums.Sum(n => n > 0 ? n : 0); // 負の値を0として集計する
Console.WriteLine(sum); // →15

Dim nums = New Integer() {1, -1, 2, -2, 3, -3, 4, -4, 5, -5}
Dim sum = nums.Sum(Function(n) If(n > 0, n, 0)) ' 負の値を0として集計する
Console.WriteLine(sum) ' →15

Sum拡張メソッドに変換関数を与えて、正の値だけを集計するコード例(上:C#、下:VB)
この他に、Enumerableクラスの拡張メソッドを使用するため、System.Linq名前空間のインポートが必要だ。
この例では、正でない値を0に変換するラムダ式をSum拡張メソッドに与えている。Sum拡張メソッドは、それぞれの要素にこのラムダ式を適用してから集計する。結果として、負の値は0として集計されることになるのである。
なお、このVBのコードでは、Visual Basic 2008で導入されたIf演算子を使っている。

 どちらの書き方でも構わないのだが、一部を除外して集計していることが明瞭なWhere拡張メソッドを使う方法が筆者の好みである。

*1 ラムダ式について詳しくは、次のMSDNのドキュメントを参照していただきたい。


null/Nothingを除外して集計するには?

 データベースから取得してくる数値はnull許容型であることも多い。null/Nothingを除外して集計するにはどうしたらよいだろうか?

 実は、Sum拡張メソッドにはnull許容型を受け取るオーバーロードも用意されている。自動的にnull/Nothingを除外して集計してくれるのだ(次のコード)。

var nullableNums = new int?[] { 1, null, 2, null, 3, null, 4, null, 5, null, };
var sum = nullableNums.Sum(); // nullを無視して集計する
Console.WriteLine(sum); // →15

Dim nullableNums = New Nullable(Of Integer)() {1, Nothing, 2, Nothing, 3, Nothing, 4, Nothing, 5, Nothing}
Dim sum = nullableNums.Sum() ' Nothingを無視して集計する
Console.WriteLine(sum) ' →15

null/Nothingを含むコレクションから数値を集計するコード例(上:C#、下:VB)
この他に、Enumerableクラスの拡張メソッドを使用するため、System.Linq名前空間のインポートが必要だ。

利用可能バージョン:.NET Framework 3.5以降
カテゴリ:クラスライブラリ 処理対象:LINQ
使用ライブラリ:Enumerableクラス(System.Linq名前空間)
関連TIPS:[LINQ]数値コレクション内の数値を集計するには?[.NET3.5、C#、VB]


「.NET TIPS」のインデックス

.NET TIPS

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。