C# の List<T>の使い方 要素の追加・検索・削除・Linqを用いて検索

はじめに

Listは動的に要素の追加や削除ができます。
配列(Array)を使っていて、配列に対して動的に要素を増やしたりで悩んだ際に、このListに行き着く人が多いのではないでしょうか。
(実際に私がそうでした)

Listを扱えるようになると、コーディングの幅が一気に広がりますので是非とも習得しましょう。
この記事では、Listの基本的な使い方について紹介します。

使い方

まず、usingステートメントに以下を宣言します。

using System.Collections.Generic;

このGeneric(ジェネリック)ですが、List型は、「型パラメータ」を利用します。
List

<T>

がGenericを指しています。
なので、usingステートメントで型パラメータを扱えるようにしておかないといけません。

Listの宣言

Listの生成

初期化する際は、以下の例の様に宣言します。

// int型のListを生成
List<int> listValue = new List<int>();

上記はint型のListですが、\<T>の部分はGenericなので他の型も指定出来ます。
例えば、以下はDictionaryを指定した際のListです。

// Dictionary<string, object>型のListを生成
List<Dictionary<string, object>> result = new List<Dictionary<string, object>>();

Listの初期化

Listは配列と同様、初期化のタイミングで値を入れる事が出来ます。

List<Dictionary<string, object>> result = new List<Dictionary<string, object>> () {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}

要素の追加

末尾に追加

末尾に追加する場合は、「add」を用います。

List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}
// 末尾に追加
result.add("test-key3", "test-value3");
途中に追加

途中に追加する場合は、「Insert」を用います。

List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}
// 2番目の要素に追加
result.Insert(2, "test-key3", "test-value3");

要素の削除

全て削除
List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}
// 全て削除
result.Clear()
指定したインデックスで削除

配列と同様に、指定したインデックスでの削除も出来ます

List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}
// 1番目の要素を削除
result.RemoveAt(1);

要素の取り出し方

配列と同様な取り出し方
List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}
// 1番目の要素を取り出す
Dictionary<string, object> element = result[1];
foreachと組み合わせる

ListはIEnumerableインタフェースを採用しているので、foreachで取り出すことが出来ます。

List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}

foreach (Dictionary<string, object>element in result) {
   // elementに上から順にresultの要素が入る
}

Linqと組み合わせる

LinqはCollectionを柔軟に扱える機能だけあって、Listとの相性が良いです。
以下はLinqの使い方と活用事例です。

使い方

usingステートメントにLinqを追加します。

using Systen.Linq;
using System.Collections.Generic;

Listの中を検索して取り出し

// dictionaryのkeyが「test-key2」の物を探す
List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}
Dictionary<string, object> element = result.Where(key => key == "test-key2");

Listの中を検索して削除

// dictionaryのkeyが「test-key2」の物を削除
List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}
result.RemoveAll(key => key == "test-key2");

存在確認

// dictionaryのkeyが「test-key2」の物があるか確認
List<Dictionary<string, object>> result = new List<Dictionary<string, object>> {
   "test-key1", "test-value1",
   "test-key2", "test-value2"
}

if (result.Ecists(key => key == "test-key2")) {
    // 存在
}

応用

応用といっても、これまでの延長線ですが、例えばゲームでHPが30未満のキャラクターに対して回復魔法を実行する機能を作ってみます

class Charactor {
    string _Name;
    int _HP;

    public GetName() {
        return _Name;
    }
    public GetHP() {
        return _HP;
    }
    public SetHP(int hp) {
        _HP = hp;
    }

    public Charactor(string name, int hp) {
        _Name = name;
        _HP     = hp;
    }
}

class Main {
    void execute() {
        List<Charactor> charactorList = new List<Charactor>() {
            new Charactor("主人公", 100);
            new Charactor("戦士", 130);
            new Charactor("僧侶", 50);
            new Charactor("魔法使い", 30);
        }
        this.Heal(charactorList);
    }

    /**
      HPが60以下のキャラを回復させる
     */
    void Heal(List<Charactor> charactorList) {
        var healTarget = persons.Where( chara => chara.HP <= 60);
        foreach (var chara in healTarget) {
            // 10回復
            chara.SetHP(chara.GetHP() + 10);
        }
    }
}

さいごに

Listはそれ単体でも拡張性の高いデータ構造で大いに役に立ちますが、Linqと組み合わさる事で、簡単に要素へのアクセス・検索ができ、コードの可読性・生産性が大いに向上しますね。
私自身、Linqなどは使い始めたばかりですが、色々使って見て便利なやり方などが見つかったら引き続き記事に記載していこうと思います。