Unityに関連する記事です

List<T>.Find(Predicate<T>) メソッド


 Find メソッドは List に用意されているメソッドの1つです。
List 内を先頭から条件に合わせて検索し、最初に条件に合致した情報を1つだけ抽出します。


参考サイト
MicroSoft
List.Find メソッド
Ararami Studio 様
C# の配列やListを検索する (Find,FindAll,FindIndex)
育児パパの人生備忘録 様
【C#】リスト型とラムダ式(Find/FindAll)


Find メソッドの使い方例


 Findメソッドは List 特定の条件を満たす最初の要素を見つけるという、よく使われる操作を提供します。
これは Find メソッドを利用しない場合には、foreach 文と if 文を利用したケースで実装されます。

 以下にFindメソッドを利用せずにforeach 文と if 文を利用したケース、Find メソッドを利用したケース、それに対応するLINQのFirstOrDefaultメソッドの使用例を示します。

 ここでは、リスト内の数値で10より大きい最初の要素を見つける処理を考えます。


<foreach 文と if 文を利用したケース>


 List 内の操作を行う場合、foreach 文と if 文による組み合わせによって、情報を精査し、必要な要素を見つけます。


List<int> numbers = new List<int> { 5, 7, 12, 20, 25 };
int firstNumberGreaterThanTen = 0;

foreach (int number in numbers)
{
    if (number > 10)
    {
        firstNumberGreaterThanTen = number;
        break;
    }
}


<Findメソッドを使用する場合>


 上記の例を踏まえて、同じ処理を Find メソッドを利用して実装してみましょう。

List<int> numbers = new List<int> { 5, 7, 12, 20, 25 };
int firstNumberGreaterThanTen = numbers.Find(number => number > 10);

 非常にシンプルな処理になりました。

 foreach 内に記述していた if 文の条件部分がラムダ式の右辺に当たる部分に利用されています。

 そのため、Find メソッドを利用して処理を置き換える場合には、従来の記述方法をしっかりと理解しておくことが大切です。

 リファクタリングを通じて、既存の処理を置き換えながら覚えていくようにするとよいでしょう。


<FirstOrDefaultメソッドを使用する場合>


 こちらのメソッドは LINQ に用意されている Find メソッドを同様の機能を持つメソッドです。
using System.Linq; を記述して利用します。


List<int> numbers = new List<int> { 5, 7, 12, 20, 25 };
int firstNumberGreaterThanTen = numbers.FirstOrDefault(number => number > 10);

 これらのコードはすべて、同じ結果(12)を返します。


List で管理しているクラスでの実装例


 Character と Item クラスを使って例を示します。

 まず、ゲーム内でキャラクターのリストを管理し、それらのキャラクターが持っているアイテムのリストを扱うシチュエーションを考えてみましょう。

 以下のようなクラス構造を想定します。

public class Item
{
    public string Name { get; set; }
    public int Value { get; set; }
}

public class Character
{
    public string Name { get; set; }
    public List<Item> Items { get; set; }
}

 ここでは、Characterのリストから、名前が特定の文字列に一致する最初のCharacterを探す処理を考えます。

 まずは初期化を行い、List の準備を整えます。

// アイテムの作成
Item sword = new Item { Name = "Sword", Value = 100 };
Item shield = new Item { Name = "Shield", Value = 150 };
Item potion = new Item { Name = "Potion", Value = 50 };

// キャラクターの作成とアイテムの割り当て
Character john = new Character 
{ 
    Name = "John", 
    Items = new List<Item> { sword, shield } 
};

Character mary = new Character 
{ 
    Name = "Mary", 
    Items = new List<Item> { potion } 
};

Character tom = new Character 
{ 
    Name = "Tom", 
    Items = new List<Item> { sword, potion } 
};

// キャラクターをリストに格納
List<Character> characters = new List<Character> { john, mary, tom };

 このサンプルコードでは、3つのキャラクター(John, Mary, Tom)を作成し、それぞれに異なるアイテムを割り当てています。
その後、作成したキャラクターをcharactersという名前のリストに格納します。

 これで、Find メソッドを使って特定のキャラクターやその所持アイテムを検索する準備ができました。


<foreach 文と if 文を利用したケース>


 抽出したCharacterの情報を代入するための変数を用意し、それから foreach 文を利用して List 内の情報を1つずつ取り出し、
if 文で判定を行い、条件に合致する Character を見つける処理です。

Character foundCharacter = null;

foreach (Character character in characters)
{
    if (character.Name == "John")
    {
        foundCharacter = character;
        break;
    }
}

 この処理の機能を理解した上で、Find メソッドへの置き換えをおこなっていきます。


<Findメソッドを使用する場合>


 上記の例を踏まえて、同じ処理を Find メソッドを利用して実装します。

Character foundCharacter = characters.Find(character => character.Name == "John");

 先ほどと同じで、こちらも非常にシンプルな処理になりました。
変数の宣言と同時に、Find メソッドを利用することで、見つけた Character の情報を Find メソッドの実行結果の戻り値として受け取る処理になっています。


<FirstOrDefaultメソッドを使用する場合>



Character foundCharacter = characters.FirstOrDefault(character => character.Name == "John");
 
 これらのコードはどちらも、名前が "John" の最初のCharacterを返します。



 このように、foreach 文と if 文を利用して List 内から必要な要素を見つける処理を記述する際には
FindメソッドやFirstOrDefaultメソッドを使うことで、条件に一致する最初の要素を探す処理を非常にシンプルに書くことができます。


LINQ 学習に向けて


 List.Findメソッドは実際にはLINQではありませんが、ラムダ式を使用してデータを操作するという点でLINQと共通しています。
よって、Find メソッドを理解することは、LINQの理解を深める上で役立ちます。

 LINQ は List の操作を行いやすくするための機能です。
そのため基本的には、foreach 文と if 文を組み合わせることで同様の処理を作成できますが、
この操作をよりシンプルに、また効率的に行うためのツールとして設計されています。

 従来のforeachループによる方法は、理解しやすく、明示的な操作を行うことができますが、コードが冗長になることがあります
特に、複雑な処理を行う場合や、複数の操作を一度に行う場合には、foreachループをネストしたり、複数のif文を組み合わせたりする必要があります。

 それに対して、LINQは、一連の操作を一行で記述することができ、コードの見通しが良くなることがあります。
また、LINQは遅延実行が可能なので、A の処理結果を使って B の値を見つける、といったように、1回の記述で必要なデータだけを効率よく処理することができます。

 ただし、パフォーマンスに留意する点や、学習のために事前に覚えることが多いため、初学者にとっては理解するのが難しい部分でもあります。

 まずはしっかりと、List の操作を行えるようにし、その後、LINQ を扱うために必要な学習(デリゲート、ラムダ式、遅延処理、ジェネリックなど)を学習していくとよいでしょう。



 => 既存の処理をリファクタリングして学ぶ LINQ 活用例

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます