LINQとは?
LINQ
とは、Language Integrated Query
の略で「リンク」と読み見ます。
コレクションなどのデータの集まりに対して、SQL
のようにデータを問い合わせる機能を
C#
言語内で統一的に使用できるようにした物です。
LINQ
を使うと、コレクションから特定のデータを選択したり、抽出したり、並び替えたり、
などの操作を簡潔に記述できます。
参考データ
以下の様なデータ用クラスが合ったとします。
public class UserData
{
public int Id;
public string Name;
public int Age;
}
適当なクラスの中で初期化したとしましょう。
using System.Collections.Generic;
using System.Linq;
public class UserDataTest : MonoBehaviour
{
private List<UserData> _userDataList;
private void Awake()
{
// 10人分のUserDataのリストを作成
_userDataList = new List<UserData>
{
new UserData { Id = 1, Name = "John", Age = 25 },
new UserData { Id = 2, Name = "Alice", Age = 30 },
new UserData { Id = 3, Name = "Bob", Age = 22 },
new UserData { Id = 4, Name = "Charlie", Age = 28 },
new UserData { Id = 5, Name = "David", Age = 35 },
new UserData { Id = 6, Name = "Eve", Age = 27 },
new UserData { Id = 7, Name = "Frank", Age = 33 },
new UserData { Id = 8, Name = "Grace", Age = 24 },
new UserData { Id = 9, Name = "Hannah", Age = 29 },
new UserData { Id = 10, Name = "Ivy", Age = 26 }
};
}
}
Awake()メソッドが呼ばれた後の、_userDataListは以下ような内容になっていることがイメージできるでしょうか?
検索する
GoogleSpreadSheet上だとフィルターを設定して条件にあうデータを絞り込むことが出来ます。
C#
では、リストの中から条件にあう特定のデータを検索するには、通常for
かforeach
で全データを調べることになります。
for(int i = 0; i < _userDataList.Count; i++)
{
// Idが5のユーザーを探す
if (_userDataList[i].Id == 5)
{
return _userDataList[i];
}
}
LINQ
を使うことで簡潔に記述することが出来ます。
Whereで指定された条件に合う要素を絞り込む
Where
メソッドを使用すると条件にある要素を絞り込んで取り出すことが出来ます。
先ほどのfor文
は以下の様に置き換えることが出来ます。
var users = _userDataList.Where(user => user.Id == 5);
Where
の引数には、_userDataList
内のUserData
が順々に渡されてきます。
条件式がtrue
になる場合は、最終的に戻り値に条件にある要素のコレクションが返ってきます。
Firstで最初に条件に合う要素を取得する
var user = _userDataList.First(user => user.Id == 5);
コレクションを先頭から調べて最初に条件にあう要素が見つかるとそれを返します。
First
に引数を渡さなければコレクションの先頭を返します。
Lastで最後に条件に合う要素を取得する
var user = _userDataList.Last(user => user.Id == 5);
コレクションを最後から調べて最初に条件にあう要素が見つかるとそれを返します。
Last
に引数を渡さなければコレクションの最後を返します。
Singleで条件に合う要素を一つだけ取得する
var user = _userDataList.Single(user => user.Id == 5);
コレクションのうち、条件にある要素を一つだけ返します。
First
と同じような挙動になるのであまり出番はないかもしれません。
Anyで条件にあう要素が1つでもあるか確認する
if (_userDataList.Any(user => user.Age <= 30))
{
// 30歳以下のユーザーがいる
}
コレクションのうち、条件にあう要素が一つでもあるか確認します。
引数を省略すると、コレクションが空かどうかを判定することも出来ます。
Allで全ての要素が条件を満たしているか確認する
if (_userDataList.All(user => user.Age >= 20)
{
// 全員が20歳以上
}
コレクションの要素が、全て条件を満たしているか確認します。
Findで条件に合う要素を取得する
var user = _userDataList.Find(user => user.Id == 5);
List
用のメソッドです。
条件にあう要素を1つだけ取得します。
First
,Sin
gleと同じ挙動になります。
FindAllで条件に合う要素を全て取得する
// 30歳以上のユーザーを全て取得
var users = _userDataList.FindAll(user => user.Age >= 30);
こちらもList
用のメソッドです。
条件にある要素を全て取得します。
Where
と同じ挙動になります。
例外
First
,Last
,Single
メソッドは、該当するデータが見つからなかった場合例外を発生させます。
try
{
var user = _users.First(user => user.Age <= 10);
}
catch(e)
{
// 見つからなかった
}
例外を処理したくない場合のために、FirstOrDefault
,LastOrDefault
,SingleOrDefault
というメソッドがあります。
これらは、データが見つからなかった場合に例外を発生させず、
コレクションの型のdefault
値を返します。
var user = _users.First(user => user.Age <= 10);
if (user == null)
{
// 見つからなかった
}
class
の場合はnull
を返すので、結果がnull
だった場合該当する要素が見つからなかったことになります。
まとめ
今回はLINQ
の検索編でした。
最初のfor文
と比べるといずれも簡潔に記述できますで、ソースコード上の見通しも良くなります。
可読性やメンテナンス性が求められる現場では、コードの見通しが良くなるというメリットは大きいでしょう。
LINQ
を使うことで、複雑なデータ操作も直感的かつ簡潔に記述できるため、開発の効率が格段に上がります。
アプリケーション開発時に大量のデータから該当するものを検索するという場面はよくあると思いますので、
LINQ
を使える機会も多いと思いますので、是非活用してみてください。