10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Unity C# Dictionaryの使い方

Last updated at Posted at 2021-09-27

##0.0 はじめに
データをまとめて扱うときに配列やListクラスがよく使われますが、それ以外にもDictionaryクラスがあります。
Dictionaryクラスではインデックス番号の代わりにKey(キー)と呼ばれる名前を使い、セットでValue(バリュー)と呼ばれる値を扱います。配列やListでindex(インデックス)番号で検索する代わりに、Key(例えば文字)で検索ができます。

👍ポイント
Keyには同じ値を使うことはできません。

##1.0 宣言及び初期化

Dictionary< Keyの型, Valueの型 > オブジェクト名 = new Dictionary< Keyの型, Valueの型 >() 

Test0.cs
// Dictionaryクラスの宣言と初期化
Dictionary<string, int> dic = new Dictionary<string, int>();

👍ポイント
Dictionaryクラスを使用した際にエラーが出る場合は、using System.Collections.Genericの呼び出しが消えていないか確認してみましょう(この宣言はUnityエディタとして使用するVisual Studioには標準で入っています。)

このように宣言と初期値の設定を同時にできます。

Test1.cs
// Dictionaryクラスの宣言と初期値の設定
Dictionary<string, int> dic = new Dictionary<string, int>(){
    {Apple, 150},
    {Orange, 100},
    {Peach, 250},       
};

##2.0 要素の追加
Addを使用して要素を追加することができます。
第一引数keyでは追加する要素のキーを指定します。第二引数valueでは追加する要素の値を指定します。
ただし、同じKeyの値を追加することはできません。

Test2.cs
// Dictionaryクラスでの要素の追加
dic.Add(Banana, 50);

##3.0 要素の取得
keyの指定でvalueが取得出来ます。
Dictionary[key]のように使います。

Test3.cs
// 要素の取得
int a = dic[Banana]; // aは50

####3.1 Keyのみの取得
Keyのみを取得するにはKeysプロパティが利用できます。

Test4.cs
// 要素の設定
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プロパティが利用できます。

Test5.cs
// Valueの表示
foreach(string value in dic.Values) {
    Debug.Log("バリューは" + value + "です。)
}
//  バリューは150です。
//  バリューは100です。
//  バリューは250です。

####3.3 KeyとValueの両方の取得
KeyValuePair構造体を使ってKeyとValueの両方を取得する方法です。

Test6.cs
// 要素の取得
foreach(KeyValuePair<string, int> item in myTable) {
    Debug.Log("キーは" + item.Key + "です。  バリューは" + item.Value + "です。");
}
//  キーはAppleです。 バリューは150です。
//  キーはOrangeです。 バリューは100です。
//  キーはPeachです。 バリューは250です。

##4.0 要素の削除
Removeを使います。

Test7.cs
// 要素の削除
dic.Remove("Banana"); // ()内はKey

##5.0 要素が含まれているかの確認
Containsを使います。

Test8.cs
dic.Add(Banana, 50);
// 要素の確認
bool flag = dic.Contains("Banana"); // flag = true

おまけ

Dictionaryクラスではindex番号(格納の順番)がないので使いにくい場合があります。
index番号を持ったDictionaryクラスを自作しました。

MyDictionary.cs
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]} です");
        }
    }
}
10
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?