#3 - Unity C#で自分が良く使うLinqの紹介 | 駆け出しゲームプログラマーの備忘録

1. そもそもLinq( リンク )とはなんぞや

Linq はズバリ、「統合言語クエリ」です!



.......何それ????????



正直、統合言語クエリが何者なのかは知らなくても、書き方・挙動さえ知っていれば Linq は実践レベルで使用できます。
なので、割愛!!! (気になる人は自分で調べてみてネ)

2. Linq の基本的な機能・書式・使用例

はい、統合言語クエリが全くわからない状態でもこの項目さえ見れば普通に使えます。
まず、このLinqが使用できるのは、普段よく使うものだと 配列、 List<>、Dictionary<>あたりが基本です。

2-1. Linq の基本的な書式

まずこれ、いつものやつで必須です。

using System.Linq;

そして、下記コードに例として Linq を使用して特定の条件に合う要素をピックアップしています。

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.Linq;

public class Example : MonoBehaviour
{
    private List<int> numberList = new List<int>()
    {
        1,4,5,7,8,9,10,20,25,40,100,101
    };

    /// <summary>
    /// 奇数の数字だけピックアップしてリストにして取得
    /// </summary>
    public List<int> GetOddNumberList()
    {
        return this.numberList.Where(v => v % 2 == 1).ToList();
    }
}

今回は例で、あるリストから奇数の数字のみを取得しリストにして取得するコードです。
この中で Linq と言われている部分は

this.numberList.Where(v => v % 2 == 1).ToList();

ハイ、ここです。
基本的には 変数.Linq(条件) のような書き方で書いていきます。
今回の処理を言葉に起こすと

numberList の中の数字を見ていって、2で割ったあまりが1になる数字のみ集めて、それをList化するで~

って感じです。
WhereとかTolistとかはまだわからなくてokです。とりあえず書き方とコードの読み方さえ分かれば問題ないです。
次はよく使うLinqの紹介をしていきます。

2-2. Where

はい、さっき例で紹介したやつです。個人的な体感ですが、一番Whereが使われがちかなと思います。

上の例で使用したものを引用して説明します。
this.numberList.Where(v => v % 2 == 1) の部分をLinqなしのコードで書くと

    /// <summary>
    /// 奇数の数字だけピックアップしてリストにして取得
    /// </summary>
    public List<int> GetOddNumberList()
    {
        List<int> oddNumList = new List<int>();

        for(int i = 0; i < this.numberList.Count; i++)
        {
            if(this.numberList[i] % 2 == 1)
            {
                oddNumList.Add(this.numberList[i]);
            }
        }

        return oddNumList;
    }

よくありがちな感じですね~。
Linqを知らない人でも、この書き方ならほとんどの人が理解できますね。
はい、というわけで Where括弧内の条件がtrueになった要素のみを取得する ものになります。
そこでわからなくなるポイント1、Whereの括弧内の式、何?
結論から言ってしまえば ラムダ式 です。

        .Where( v => v % 2 == 1) 

この v は上の Linqなしver.で言うthis.numberList[i] の部分です。
つまり v => v % 2 == 1 というのは
Whereがリスト内すべての要素にアクセスし、その各要素ごとに v % 2 == 1 の条件で調べていき、すべての要素が調べ終わった際に該当したもののみ取得している
ということなのです。

Whereを使用するメリット

・コードを書く量が圧倒的に減る
Linqは基本バグらないので、自身でコードを書くよりも圧倒的にバグりにくい
・ゲームの持ち物リストなどで、「回復アイテムのみ表示」「武器のみ表示」などの ~のみ表示系のソートが一発で作れる

デメリット

・これはLinqを使う上では共通だが、Linqの書式や仕組みを知らないと意味が分からない
・基本的に対象リストすべての要素にアクセス→条件分岐を使用しているため、要素数や条件によっては処理に時間がかかる
・.Where(~~~).Where(~~~).Where(~~~)...... などで絞込をいくつもつけられるが、コードが横長になって見にくい( .の手前で改行とかがオススメ)




他にも .Select() .ToList() .Any() .All() .FirstOrDefault() などなど便利なやつがたくさんありますが、今回は疲れたので一旦ここまでにします