Unity - LINQについて① -
初めに
C# を使う上で便利な LINQ についてまとめます。コレクション(配列や List など)の要素を処理するメソッドを集めたものになります。要素を調べたいとき、要素を取得したいときに使える関数を本記事では書いています。
Index
LINQ とは
LINQ とは、C# で使われる統合言語クエリ(LINQ: Language-Integrated Query)と呼ばれるものになります。配列や List などの用をを処理する関数を集めたものです。
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 の関数はまだあります。次の記事で今回書いていない関数をまとめます。