ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

Unity - LINQについて② -

初めに

 C# を使う上で便利な LINQ についてまとめます。コレクション(配列や List など)の要素を処理するメソッドを集めたものになります。最大値や平均値など要素内での計算、配列や List を変換するための関数をまとめます。

LINQ とは

 LINQ とは、C# で使われる統合言語クエリ(LINQ: Language-Integrated Query)と呼ばれるものになります。配列や List などの用をを処理する関数を集めたものです。

LINQ の使い方

 下記の文を名前空間(一番上)に追加すれば使うことができるようになります。

using System.Linq;

以前紹介した関数

fineworks-fine.hatenablog.com

(紹介した関数の一覧)

  • All
  • Any
  • Contains
  • OfType
  • SequenceEqual
  • Count
  • First、FirstOrDefault
  • Last、LastOrDefault
  • Single、SingleOrDefault
  • ElementAt、ElementAtDefault
  • Skip、SkipWhile
  • Take、TakeWhile
  • DefaultIfEmpty
  • Where

LINQ の関数

Max、Min

 Max は最大値、Min は最小値を返します。

int[] Num = {1, 2, 3, 4, 5, 6, 7};

    void Start()
    {
      Debug.Log(Num.Max());
      //7
      Debug.Log(Num.Min());
      //1
    }
Sum、Average

 Sum は合計値、Average は平均値を返します。

int[] Num = {1, 2, 3, 4, 5, 6, 7};

    // Start is called before the first frame update
    void Start()
    {
      Debug.Log(Num.Sum());
      //28
      Debug.Log(Num.Average());
      //4
    }
Aggregate

 Aggregateは集計を意味します。関数を適用した結果を返します。第一引数に初期値としてシード値を設定することもできます。第一引数に何も指定しなければ 1 からスタートします。

int[] Num = {1, 2, 3};

    // Start is called before the first frame update
    void Start()
    {
      Debug.Log(Num.Aggregate((x, next) => x + next * 3));
      //15 (1 + 2 * 3 + 3 * 3) 
      Debug.Log(Num.Aggregate(10, (x, next) => x + next * 3));
      //28 (10 + 1 * 3 + 2 * 3 + 3 * 3)
    }
ToArray

 List など配列でないものを配列に変換します。

List<int> data = new List<int>() {2, 4, 6, 8};

    void Start()
    {
      int[] array = data.ToArray();
    }
ToList

 配列など List でないものを List に変換します。

int[] array = new int[] {3, 6, 9, 12};

    void Start()
    {
      List<int> data = array.ToList();
    }
ToDictionary

 配列や List をDictionary に変換します。

Dictionary は Key と Value とよばれる値のセットで定義されます。

Dictionary< Keyの型, Valueの型 > オブジェクト名 = new Dictionary< Keyの型, Valueの型 >()

// Dictionaryクラスの宣言と初期値の設定
Dictionary<string, int> dic = new Dictionary<string, int>(){
    {aaa, 150},
    {bbb, 100},
    {ccc, 250},       
};

 ToDictionary は下記のように使われます。

Parameter[] parameters = new Parameter[]
    {
          new Parameter() { ID = 0, Name = "aaa" },
          new Parameter() { ID = 8, Name = "bbb" },
    };

    void Start()
    {
      Dictionary<int, string> dic = parameters.ToDictionary(x => x.ID, y => y.Name);
      Debug.Log(dic[0]);
      //aaa
      Debug.Log(dic[8]);
      //bbb
    }

    private class Parameter
    {
        public int      ID      { get; set; }
        public string   Name    { get; set; }
    }
AsEnumerable

 IEnumerable として型指定された入力を返します。
 関数名などが被った場合、LINQ の関数を呼び出すには、LINQ から関数を呼び出していることを指示する必要があります。その場合に使います。

int[] Num = new int[] {1, 3, 5, 7};

    // Start is called before the first frame update
    void Start()
    {
      bool value = Num.AsEnumerable().Any(x => x < 0);
      Debug.Log(value);
      //false
    }
Cast

 要素を指定した型にキャスト(変換)します。

ArrayList list = new ArrayList {"aa", "bb", "cc"};

    // Start is called before the first frame update
    void Start()
    {
      var result = list.Cast<string>();
    }

 List 内に変換できないものがあるとエラーになります。

Reverse

 要素を逆順に並び替えます。

int[] Num = new int[] {1, 2, 3, 4, 5};

    // Start is called before the first frame update
    void Start()
    {
      var reverse = Num.Reverse();
      //5, 4, 3, 2, 1
    }
Distinct

 重複を除いたシーケンスを返します。

int[] Num = new int[] {1, 1, 1, 2, 2, 3, 4};

    void Start()
    {
      var result = Num.Distinct();
      //1, 2, 3, 4
    }
Select

 各要素すべてに処理を行い、その結果を1つのシーケンスとして返します。

int[] Num = new int[] {1, 3, 5, 7};

    // Start is called before the first frame update
    void Start()
    {
      var result = Num.Select(x => x * 3);
      //3, 9, 15, 21
    }
SelectMany

 各要素すべてに処理を行い、その結果を1つのシーケンスに平坦化します。List 内に複数の List がある場合に、一つの List としてまとめるような処理を平坦化といいます。

List<int[]> lists = new List<int[]>
    {
      new int[] {1, 3, 5, 7},
      new int[] {2, 4, 6, 8}
    };

    // Start is called before the first frame update
    void Start()
    {
      var result = lists.SelectMany(x => x);
      //1, 3, 5, 7, 2, 4, 6, 8
    }

最後に

 並べ替えや複数の配列を合体させるものなど、LINQ ではまだ紹介できていない関数があります。それらはまた次回まとめます。