##0.0 はじめに
データをまとめて扱うときに配列やListクラスがよく使われますが、それ以外にもDictionaryクラスがあります。
Dictionaryクラスではインデックス番号の代わりにKey(キー)と呼ばれる名前を使い、セットでValue(バリュー)と呼ばれる値を扱います。配列やListでindex(インデックス)番号で検索する代わりに、Key(例えば文字)で検索ができます。
👍ポイント
Keyには同じ値を使うことはできません。
##1.0 宣言及び初期化
Dictionary< Keyの型, Valueの型 > オブジェクト名 = new Dictionary< Keyの型, Valueの型 >()
// Dictionaryクラスの宣言と初期化
Dictionary<string, int> dic = new Dictionary<string, int>();
👍ポイント
Dictionaryクラスを使用した際にエラーが出る場合は、using System.Collections.Genericの呼び出しが消えていないか確認してみましょう(この宣言はUnityエディタとして使用するVisual Studioには標準で入っています。)
このように宣言と初期値の設定を同時にできます。
// Dictionaryクラスの宣言と初期値の設定
Dictionary<string, int> dic = new Dictionary<string, int>(){
{Apple, 150},
{Orange, 100},
{Peach, 250},
};
##2.0 要素の追加
Addを使用して要素を追加することができます。
第一引数keyでは追加する要素のキーを指定します。第二引数valueでは追加する要素の値を指定します。
ただし、同じKeyの値を追加することはできません。
// Dictionaryクラスでの要素の追加
dic.Add(Banana, 50);
##3.0 要素の取得
keyの指定でvalueが取得出来ます。
Dictionary[key]のように使います。
// 要素の取得
int a = dic[Banana]; // aは50
####3.1 Keyのみの取得
Keyのみを取得するにはKeysプロパティが利用できます。
// 要素の設定
Dictionary<string, int> dic = new Dictionary<string, int>(){
{Apple, 150},
{Orange, 100},
{Peach, 250},
};
// Keyの表示
foreach(string key in dic.Keys) {
Debug.Log("キーは" + key + "です。)
}
// キーはAppleです。
// キーはOrangeです。
// キーはPeachです。
👍ポイント
Dictionaryクラスではindex番号(格納の順番)はありません。このためループ処理にはforeachを使います。
####3.2 Valueのみの取得
Valueのみを取得するにはValuesプロパティが利用できます。
// Valueの表示
foreach(string value in dic.Values) {
Debug.Log("バリューは" + value + "です。)
}
// バリューは150です。
// バリューは100です。
// バリューは250です。
####3.3 KeyとValueの両方の取得
KeyValuePair構造体を使ってKeyとValueの両方を取得する方法です。
// 要素の取得
foreach(KeyValuePair<string, int> item in myTable) {
Debug.Log("キーは" + item.Key + "です。 バリューは" + item.Value + "です。");
}
// キーはAppleです。 バリューは150です。
// キーはOrangeです。 バリューは100です。
// キーはPeachです。 バリューは250です。
##4.0 要素の削除
Removeを使います。
// 要素の削除
dic.Remove("Banana"); // ()内はKey
##5.0 要素が含まれているかの確認
Containsを使います。
dic.Add(Banana, 50);
// 要素の確認
bool flag = dic.Contains("Banana"); // flag = true
おまけ
Dictionaryクラスではindex番号(格納の順番)がないので使いにくい場合があります。
index番号を持ったDictionaryクラスを自作しました。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//******************************
// 自作クラス DictionaryにIndex番号を搭載したクラス
// index(int)でkey(string)とvalue(int)を管理
// AddでKeyを追加していくと自動でDictionaryを生成する
// 要素数(keyの種類)はindexMaxで取り出す
//******************************
public class MyDictionary {
//int index; // 要素番号(Addした順番に格納される)
public int indexMax = 0; // keyの種類数
List<string> Keys = new List<string>(); // keyの格納リスト
List<int> Values = new List<int>(); // valueの格納リスト
/// <summary>
/// 要素を追加する(同じkeyがある場合はvalueを1増やす、ない場合は追加する)
/// </summary>
public void Add(string key) {
if (Keys.Contains(key)) { // すでにKeyがあった場合はqtyを増やす
Values[GetIndexByKey(key)]++;
} else { // ない場合はKeyを新しく追加、qtyを1
Keys.Add(key);
Values.Add(1);
indexMax++;
}
}
/// <summary>
/// 特定のkey(str)が含まれているか 含まれていればtrue
/// </summary>
public bool Contains(string key) {
if (Keys.Contains(key))
return true;
return false;
}
/// <summary>
/// keyのindex番号取得、含まれていない場合は-1を返す
/// </summary>
int GetIndexByKey(string key) {
if (!Keys.Contains(key))
return -1;
return Keys.IndexOf(key);
}
/// <summary>
/// 要素番号(index)からkeyを取得 引数:調べたいKeyの要素番号
/// </summary>
public string GetKeyByIndex(int index) {
return Keys[index];
}
/// <summary>
/// 要素番号(index)から数を取得 引数:調べたいKeyの要素番号
/// </summary>
public int GetQtyByIndex(int index) {
return Values[index];
}
/// <summary>おまけ
/// keyから全種類においての通し番号を取得 (1種類の最初の番号)
/// keyがなければ-1を返す
/// </summary>
public int GetSerialIndexByKey(string key) {
int serialIndex = 0; // 通し番号カウント用
for (int i = 0; i < Keys.Count; i++) { // k
if (Keys[i] == key) { // 同じkeyに当たれば検索終了
break;
}
serialIndex += Values[i]; // なければそこまでの数をIndexに加える
}
// 以下keyが含まれてない場合-1を返す
int sum = 0; // 全種類の合計数
for (int i = 0; i < Values.Count; i++) {
sum += Values[i];
}
if (serialIndex == sum) { // 最後まで言った場合はkeyがなかったということ
return -1;
} else
return serialIndex;
}
// テスト用(Dicの中身をコンソール画面に表示する)
public void Test() {
for (int i = 0; i < indexMax; i++) {
Debug.Log($"{i}番目のkeyは {Keys[i]} で、valueは {Values[i]} です");
}
}
}