ゲーマーときどきエンジニア

基本ゲーム記事を書いて、ときどき考えを発信するエンジニアのブログです!

【C#】【LINQ】Aggregateメソッドの使い方を解説します

こんにちは。たいら(@tairaengineer2)です。
この記事では、C#LINQAggregateメソッドの使い方について解説します。

スポンサーリンク

 

前提条件

この記事では、Visual Studio 2017 Communityを使っています。
インストールの仕方は、下の記事をご参考ください。

www.tairax.com

Aggregateメソッドとは

Aggregateを日本語訳すると

【自動】
集まる、一体になる、総計で(~に)なる
【他動】
集める、合計する、統合する
総計で~になる

Aggregateの意味・使い方|英辞郎 on the WEB:アルクから引用させて頂きました

の日本語訳の通り、いろいろな使い方があり、リストにも配列にも使える集計関数です。
例えば、あるリストの合計を出したり、リストの中の最大値を求めたりできます。

では、実際に使ってみます。

解説するプログラムの概要

Aggregateメソッドは、初期値を設定するかどうかを選択することができます。

解説では2つプログラムを作成します。
1つ目は初期値なし、2つ目は初期値ありのプログラムを作成します。

どちらのプログラムも、その結果をコンソールに表示します。
コンソールプロジェクトを作成するやり方は下の記事をご参考ください。

www.tairax.com

プログラムを作成したあと、ビルドをするやり方はこちらの記事をご参考ください。

www.tairax.com

解説その1:初期値なし

Aggregate<TSource>(IEnumerable<TSource>, Func<TSource,TSource,TSource>)
シーケンスにアキュムレータ関数を適用します。
public static TSource Aggregate<TSource> (this System.Collections.Generic.IEnumerable<TSource> source, Func<TSource,TSource,TSource> func);

Enumerable.Aggregate Method (System.Linq) | Microsoft Docsから引用させて頂きました

アキュムレータ関数とは、演算結果を累積し総和を得るときに使う関数です。

アキュムレータ(英: Accumulator)は、コンピュータにおいて、演算装置による演算結果を累積する、すなわち総和を得るといったような計算に使うレジスタや変数のことである。
特にプロセッサにあるそのようにして使える唯一のレジスタを指すことがあるがその意味では、ジャーゴンファイルのaccumulatorの項の冒頭に "Archaic term for a register." とあるように、基本的には古語である。

アキュムレータ (コンピュータ) - Wikipediaから引用させて頂きました

ぶっちゃけ何を言ってるのか分かりません(;'∀')
実際に使って解説します。

1つ目のプログラムは、int型の配列を用意し、その配列の合計値を出すプログラムです。

C#

using System;
using System.Linq;

/// <summary>
///  Aggregateメソッドの練習クラスその1
/// </summary>
namespace ConsoleApp1
{
    class Program
    {
        /// <summary>
        /// メイン
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            int sumNumber = numbers.Aggregate((sum, number) => sum += number);
            Console.WriteLine("配列の合計値:{0}", sumNumber);
        }
    }
}

実行結果

f:id:Tairax:20190124223258p:plain

配列の合計値:55
続行するには何かキーを押してください . . .

では、解説します。

解説

Aggregateメソッドを使っているのはここです。

int sumNumber = numbers.Aggregate((sum, number) => sum += number);

の中の処理のを重点的に解説します。

引数の後ろをどういう風に処理しているかと言いますと。

f:id:Tairax:20190125081419p:plain

  1. numberにnumbersの要素を設定
  2. sumとnumberを足したものをsumに設定
  3. 以下1,2をnumbersの要素が無くなるまで繰り返し

という風に処理をしています。
最終的にsumNumberにnumbersの合計が設定されます。

Aggregateメソッドの引数の流れは次のようになっています。

回数 sum number 計算後のsum
1回目 0 1 1
2回目 1 2 3
3回目 3 3 6
4回目 6 4 10
5回目 10 5 15
6回目 15 6 21
7回目 21 7 28
8回目 28 8 36
9回目 36 9 45
10回目 45 10 55

このように足していって、最終的にsumNumberに合計値が設定されています。

 

スポンサーリンク

 

解説その2:初期値あり

Aggregate<TSource,TAccumulate,TResult>(IEnumerable<TSource>, TAccumulate, Func<TAccumulate,TSource,TAccumulate>, Func<TAccumulate,TResult>)
シーケンスにアキュムレータ関数を適用します。
指定したシード値は最初のアキュムレータ値として使用され、指定した関数は結果値の選択に使用されます。
public static TResult Aggregate<TSource,TAccumulate,TResult> (this System.Collections.Generic.IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate,TSource,TAccumulate> func, Func<TAccumulate,TResult> resultSelector);

Enumerable.Aggregate Method (System.Linq) | Microsoft Docsから引用させて頂きました

1つ目でも解説しましたが、アキュムレータ関数とは、演算結果を累積し総和を得るときに使う関数です。

こっちも何を言ってるのか分かりません(;'∀')
実際に使って解説します。

2つ目のプログラムは、stringのリストを作成します。
そのリストに対して初期値を設定し、リストの中で1番長い文字列を抽出するプログラムです。

C#

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

/// <summary>
///  Aggregateメソッドの練習クラスその2
/// </summary>
namespace ConsoleApp1
{
    class Program
    {
        /// <summary>
        /// メイン
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            List<string> vegetableList = 
                new List<string>{ "トマト", "ニンジン", "ダイコン", "キャベツ" };

            string longVegetableName =
                vegetableList.Aggregate(
                    "ホウレンソウ", (longName, next) => next.Length > longName.Length ? next : longName);
            Console.WriteLine("最も長い文字列の野菜は{0}",longVegetableName);
        }
    }
}

実行結果

f:id:Tairax:20190123222346p:plain

最も長い文字列の野菜はホウレンソウ
続行するには何かキーを押してください . . .

では、解説します。

解説

Aggregateメソッドを使っているのはここです。

string longVegetableName =
    vegetableList.Aggregate(
        "ホウレンソウ", (longName, next) => next.Length > longName.Length ? next : longName);

の中の処理のを重点的に解説します。

その1と比べて、初期値を設定しています。
それは

f:id:Tairax:20190124221301p:plain

この赤枠で囲っている部分です。

この初期値と引数の後ろをどういう風に処理しているかと言いますと。

f:id:Tairax:20190124221536p:plain

  1. longNameに初期値"ホウレンソウ"を設定
  2. nextにvegetableListの要素を設定
  3. 三項演算子でnextとlongNameの長さを比較
  4. 長い方をlongNameに設定
  5. 以下2~4をvegetableListの要素が無くなるまで繰り返し

という風に処理をしています。
最終的にlongVegetableNameにvegetablesの中で最も長い文字列が設定されます。

Aggregateメソッドの引数の流れは次のようになっています。

回数 longName next
1回目 ホウレンソウ トマト
2回目 ホウレンソウ ニンジン
3回目 ホウレンソウ ダイコン
4回目 ホウレンソウ キャベツ

こういう風にAggregateメソッドは、リストの中から値を抽出することもできます。

 

スポンサーリンク

 

まとめ:何かを集計するときはAggregateメソッドを使おう!

以上がAggregateメソッドの解説です。
何かを集計するときはAggregateメソッドを使いましょう!

あなたのご参考になったのなら、とても嬉しいです(*´▽`*)
ではでは~(・ω・)ノシ

 

ほかにもC#勉強記事を書いてます。
よければご参考ください。

【C#】xmlを読み込む、XDocumentとXElementについて解説します。

【C#】配列からListに変換するやり方を解説します

【Visual Stadio】mdfファイル(データベース ファイル)を接続するやり方を解説します

 

今までブログで書いたC#の解説記事のまとめは、こちらをご参考ください。

【C#】ブログで書いた文法記事のまとめ