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

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

Unity - LINQについて① -

初めに

 C# を使う上で便利な LINQ についてまとめます。コレクション(配列や List など)の要素を処理するメソッドを集めたものになります。要素を調べたいとき、要素を取得したいときに使える関数を本記事では書いています。

LINQ とは

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

LINQ の使い方

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

using System.Linq;

LINQ の関数

All

 リストや配列の要素が全て特定の条件を満たしているかを調べたいときに使う bool 関数になります。

int[] Numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    void Start()
    {
      Debug.Log(Numbers.All(x => x == 1));
      //false

      Debug.Log(Numbers.All(x => x <= 10));
      //true

      Debug.Log(Numbers.All(x => x % 2 == 0));
      //false
    }

 なお、空のリストに関して、All を用いると必ず true が返ってきます。下記のスクリプトでは、Numbers の要素が空のため、All 関数の条件を何にしても true を返します。

int[] Numbers = {};

    void Start()
    {
      Debug.Log(Numbers.All(x => x == 1));
      //true

      Debug.Log(Numbers.All(x => x <= 10));
      //true

      Debug.Log(Numbers.All(x => x % 2 == 0));
      //true
    }

 

Any

 リストや配列の要素の中に条件を満たすものがあれば true を返します。

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

    void Start()
    {
      Debug.Log(Numbers.Any(x => x == 2));
      //true

      Debug.Log(Numbers.Any(x => x > 5));
      //false

      Debug.Log(Numbers.Any(x => x % 2 == 0));
      //true
    }

 空のリストに関しては、条件を満たすものがないと判定され、false を返します。

Contains

 リストや配列の中に含まれるかどうか判定する bool 関数です。引数は調べたいリスト、配列と同じ型になります。下記スクリプトでは Numbers は int の配列のため、引数は int になっています。

int[] Numbers = {1, 2, 3, 4, 5};
string[] Texts = {"abc", "def", "ghi"};

    void Start()
    {
      Debug.Log(Numbers.Contains(2));
      //true

      Debug.Log(Numbers.Contains(6));
      //false

      Debug.Log(Texts.Contains("abc"));
      //true

      Debug.Log(Texts.Contains("aaa"));
      //false
    }
OfType

 リストに含まれる特定のクラスだけほしい場合に使えます。

ArrayList list = new ArrayList(){1, 4, 0.25f, "aa"};

    void Start()
    {
      var listint = list.OfType<int>();
      //listint {1, 4}
      Debug.Log(listint.Contains(1));
      //true
      
      var liststring = list.OfType<string>();
      //liststring {"aa"}
      Debug.Log(liststring.Contains("ab"));
      //false
    }
SequenceEqual

 配列や要素が同じものか判定する bool 関数です。順番も含めて同じ場合に true を返します。

    int[] Num1 = {1, 2, 3, 4, 5};
    int[] Num2 = {1, 2, 3, 4, 5};
    int[] Num3 = {2, 3, 1, 4, 5};
    int[] Num4 = {1, 2, 3};

    void Start()
    {
      Debug.Log(Num1.SequenceEqual(Num2));
      //true
      Debug.Log(Num1.SequenceEqual(Num3));
      //false
      Debug.Log(Num1.SequenceEqual(Num4));
      //false
    }
Count

 配列やリストの要素数を取得することができます。配列には Length プロパティ、リストは Count プロパティ を使うことで要素数を取得できますが、LINQ のCount は関数のため、条件を書くことができます。

int[] Num = {1, 10, 100, 1000};

    void Start()
    {
      Debug.Log(Num.Count());
      //4
      Debug.Log(Num.Count(x => x >= 100));
      //2
    }
First、FirstOrDefault

 First は最初の要素を返します。

int[] Num = {3, 2, 4, 1};
string[] Texts = {"sss", "ttt", "uuu"};

    void Start()
    {
      Debug.Log(Num.First());
      //3
      Debug.Log(Num.First(x => x > 3));
      //4
      Debug.Log(Texts.First());
      //"sss"
    }

 First は条件を満たす要素がない場合、エラーが出ます。FirstOrDefault は条件を満たす要素がない場合、既定値(int ならば 0、string ならば null など)を返します。

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

    void Start()
    {
      Debug.Log(Num.FirstOrDefault(x => x > 10));
      //0
    }
Last、LastOrDefault

 Last は最後の要素を返します。LastOrDefault は条件を満たす要素がない場合、既定値(int ならば 0、string ならば null など)を返します。
 ※スクリプトの書き方は First と同じです。

Single、SingleOrDefault

 Single は一つの特定の要素を返します。条件を満たす要素が複数ある場合はエラーになります。

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

    void Start()
    {
      Debug.Log(Num.Single(x => x > 4));
      //5
      Debug.Log(Num.Single(x => x < 3));
      //エラー
    }

 SingleOrDefault は条件を満たすものがない場合に既定値(int ならば 0、string ならば null など)を返します。複数の要素が条件を満たす場合はエラーとなります。

ElementAt、ElementAtDefault

 指定した順番にある要素を返します。

int[] Num = {3, 5, 23, 10};

    void Start()
    {
      Debug.Log(Num.ElementAt(2));
      //23
    }

 Element では、インデックスの範囲外の場合はエラーになります。ElementAtDefault では、インデックスの範囲外の場合は既定値を返します。

Skip、SkipWhile

 Skip は先頭から指定した数の要素をスキップし、残りを返します。SkipWhile は指定した条件が満たされる限り先頭から要素をスキップした後、残りの要素を返します。

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

    void Start()
    {
       var result1 = Num.Skip(3);
       //4, 5, 6, 7
       var result2 = Num.SkipWhile(x => x < 3);
       //3, 4, 5, 6, 7
    }
Take、TakeWhile

 Take は先頭から指定した数の要素を返します。TakeWhile は指定した条件が満たされる限り要素を取得し、残りの要素はスキップします。

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

    void Start()
    {
       var result1 = Num.Take(3);
       //1, 2, 3
       var result2 = Num.SkipWhile(x => x < 3);
       //1, 2
    }
DefaultIfEmpty

 シーケンスを返します。シーケンスが空の場合は規定値もしくは任意の要素を返します。
docs.microsoft.com

Where

 条件を見たす要素をすべて返します。

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

    void Start()
    {
      var result = Num.Where(x => x > 3);
      //4, 5, 6, 7
    }

最後に

 LINQ の関数はまだあります。次の記事で今回書いていない関数をまとめます。