C# LINQメモ書き


LINQを勉強したのでまとめました。独断と偏見で便利そうだな思ったものだけまとめます。

LINQとは

Language INtegrated Queryの略で「統合言語クエリ」と訳されています。何を統合しているかというと、「データベース問い合わせ」と「オブジェクト指向プログラミング(OPP)への問い合わせ」の統合です。データベース問い合わせでは「どのデータ集合から」「どんな条件で」「どんな順番で」「どのカラムを」取得するかをクエリによって指定できます。LINQを使うと、これらをオブジェクトに対して行うことができます。

実際にやってみる

準備するデータ

下記のようなモデルを用意する。

public class LinqTestModel : MonoBehaviour {

    private int id;
    public int Id{set{id=value;}get{return id;}}

    private string name;
    public string Name{set{name=value;}get{return name;}}

    private int attack;
    public int Attack{set{attack=value;}get{return attack;}}

    private int defense;
    public int Defense{set{defense=value;}get{return defense;}}

    private int speed;
    public int Speed{set{speed=value;}get{return speed;}}

    public LinqTestModel(int id, string name, int attack, int defense, int speed)
    {
        this.id = id;
        this.name = name;
        this.attack = attack;
        this.defense = defense;
        this.speed = speed;
    }

    public void ShowStatus()
    {
        Debug.Log ("id: " + id + ", name: " + name + ", attack: " + attack + ", defense: " + defense + ", speed: " + speed);
    }
}

上記モデルにデータを入れて、それをリストに格納していく。

List<LinqTestModel> linqList = new List<LinqTestModel> ();
// id: 1
linqList.Add (new LinqTestModel(1,"AAAAA",100,150, 20));
// id: 2
linqList.Add (new LinqTestModel(2,"BBBBB", 40,10, 50));
// id: 3
linqList.Add (new LinqTestModel(3,"CCCCC",150,300, 10));
// id: 4
linqList.Add (new LinqTestModel(4,"DDDDD",100,40, 5));

データの準備ができたので早速LINQを使っていろいろ試していきたいと思います。

Where

条件に合う要素のみ取得します。

var list = linqList.Where (elem => elem.Attack >= 100);

Attackが100以上の要素を取得します。

id: 1, name: AAAAA, attack: 100, defense: 150, speed: 20
id: 3, name: CCCCC, attack: 150, defense: 300, speed: 10
id: 4, name: DDDDD, attack: 100, defense: 40, speed: 5

id: 2はAttackが40なので除外されています。
次はNameに[A]が含まれている要素を取得してみます。

var list = linqList.Where (elem => elem.Name.Contains ("A"));

結果:

id: 1, name: AAAAA, attack: 100, defense: 150, speed: 20

次に複数条件でもやってみます。

var list = linqList.Where (elem => elem.Attack >= 100 && elem.Defense > 80);

Attackが100以上でDefenseが80より大きい要素を取得します。
結果:

id: 1, name: AAAAA, attack: 100, defense: 150, speed: 20
id: 3, name: CCCCC, attack: 150, defense: 300, speed: 10

OrderBy

指定したメンバによるソートを行います。

var list = linqList.OrderBy (elem => elem.Attack);

Attackでソートします(昇順)。
結果:

id: 2, name: BBBBB, attack: 40, defense: 10, speed: 50
id: 1, name: AAAAA, attack: 100, defense: 150, speed: 20
id: 4, name: DDDDD, attack: 100, defense: 40, speed: 5
id: 3, name: CCCCC, attack: 150, defense: 300, speed: 10

次に降順でソートしてみます。降順にするには先ほどのOrderByをOrderByDescendingに変更します。

var list = linqList.OrderByDescending (elem => elem.Attack);

結果:

id: 3, name: CCCCC, attack: 150, defense: 300, speed: 10
id: 1, name: AAAAA, attack: 100, defense: 150, speed: 20
id: 4, name: DDDDD, attack: 100, defense: 40, speed: 5
id: 2, name: BBBBB, attack: 40, defense: 10, speed: 50

複数のメンバでソートしたい場合は、OrderByとThenByを使います。

var list = linqList.OrderBy (elem => elem.Attack).ThenBy(elem => elem.Speed);

Attackの昇順、もしAttackが同値の場合Speedを評価して順番を決めます。
結果:

id: 2, name: BBBBB, attack: 40, defense: 10, speed: 50
id: 4, name: DDDDD, attack: 100, defense: 40, speed: 5
id: 1, name: AAAAA, attack: 100, defense: 150, speed: 20
id: 3, name: CCCCC, attack: 150, defense: 300, speed: 10

Take

リストの先頭からいくつ要素を取得するかを指定できます。

var list = linqList.Take (3);

先頭から3つ要素を取得します。
結果:

id: 1, name: AAAAA, attack: 100, defense: 150, speed: 20
id: 2, name: BBBBB, attack: 40, defense: 10, speed: 50
id: 3, name: CCCCC, attack: 150, defense: 300, speed: 10

All, Any

指定した条件に合う要素があるかbool値で返します。

All: 要素全てが条件に当てはまっているかを判定
Any: 要素のどれか一つでも条件に当てはまっているかを判定

bool judge = linqList.All (elem => elem.Defense > 50);

全ての要素のDefenseが50より大きいか判定します。
結果:

False

id: 2のDefenseが10なのでFalseが返ってきます。

ではこれをAnyにしてみます。
結果:

True

となりました。

Linqに関して今後また追記していきます。
最後までお読みいただきありがとうございました。