はじめに
C#でリスト中から重複せずに要素を取り出した場面があったので、いい感じのクラスを書きました。Unityで使ってますが、ログ出力部分以外はC#でも使えます。CC0なのでよかったら活用してください。
Gist: UniqueItemPicker.cs
使い方
test.cs
usingUnityEngine;publicclasstest:MonoBehaviour{voidStart(){// 配列を用意するvarnameList=newstring[]{"なかじ","リリカちゃん","ゴリラ",};// 配列を渡して初期化varenemyNameGenerator=newUniqueItemPicker<string>(nameList);// 要素を取り出すDebug.Log(enemyNameGenerator.GetUniqueItem());Debug.Log(enemyNameGenerator.GetUniqueItem());Debug.Log(enemyNameGenerator.GetUniqueItem());Debug.Log(enemyNameGenerator.GetUniqueItem());// null// 履歴を削除enemyNameGenerator.ResetUsageHistory();// 再び取り出せるようになるDebug.Log(enemyNameGenerator.GetUniqueItem());Debug.Log(enemyNameGenerator.GetUniqueItem());}}
出力
初期化した時の要素を使い終わるとNull
が返ってくる点に注意してください。そうなった場合、enemyNameGenerator.ResetUsageHistory()
を呼び出すことで再度要素を取得することができます。
ソースコード
Gist: UniqueItemPicker.cs
UniqueItemPicker.cs
usingSystem.Collections.Generic;/// <summary>/// リスト中から重複せずに要素を取り出すクラス/// </summary>publicclassUniqueItemPicker<T>{T[]AllItems;/// <summary>/// コンストラクタ/// </summary>/// <param name="allItems">取り出したい要素の配列</param>publicUniqueItemPicker(T[]allItems){AllItems=allItems;InitIndexList();}voidInitIndexList(){indexList.Clear();for(inti=0;i<AllItems.Length;i++){indexList.Add(i);}}/// <summary>/// リスト中から重複せずに要素を取り出す/// </summary>publicTGetUniqueItem(){if(indexList.Count==0){UnityEngine.Debug.LogError("要素がありません");returndefault(T);}returnAllItems[GetIndex()];}List<int>indexList=newList<int>();intGetIndex(){intindex=UnityEngine.Random.Range(0,indexList.Count);intresult=indexList[index];indexList.RemoveAt(index);returnresult;}/// <summary>/// 使用履歴を初期化する/// </summary>publicvoidResetUsageHistory(){InitIndexList();}}
ジェネリック型で作っているので構造体やクラスも扱えて便利です。型を限定していないので、要素がない時は default(T)
を返しているところがポイントです。
最後に
役に立ったらいいねください!!