C#のDictionaryとは?定義方法と基本的な使い方【初心者向け】

公開日:2021.10.18

スキルアップ
 

C#には、「Dictionary」というクラスがあり、何かと便利に利用できます。本記事では、C#のDictionaryの宣言・定義方法・初期化と、具体的な使い方について、サンプルコードを示しながら解説します。また、Listとの違いや、特殊な操作をした場合にどのような挙動になるかについてもまとめましたので、ぜひ参考にしてみてください。

C#のDictionaryとは

C#のDictionaryは、Keyと呼ばれる名前と、Valueと呼ばれる値をセットで扱う連想配列です。Listの場合は、インデックス番号と値をセットで扱いますが、Dictionaryではインデックス番号の代わりにKeyを使って値を取り出します。1つのDictionaryに、同じKeyは保持できません。

以降では、C#のDictionaryの定義方法と基本的な使い方を紹介します。

C#のDictionaryの定義方法

C#のDictionaryの定義方法を宣言・定義・構造体・初期化の順番に解説します。

Dictionaryの宣言

C#のDictionaryを使用するには、以下の宣言が必要です。

using System.Collections.Generic;

Dictionaryの宣言は、以下の通りです。

【宣言】
Dictionary<データ型1, データ型2> 変数名 = new Dictionary<データ型1, データ型2>();

上記の宣言により、Dictionaryをインスタンス化します。Dictionaryは、Keyのデータ型とValueのデータ型の両方を指定することが必要です。

Dictionaryの定義

実際に、Dictionaryを定義したサンプルコードは、以下の通りです。

using System.Collections.Generic;

public class MyDic {
  public static void Main() {
    //Dictionaryクラスをmydic1としてインスタンス化
    var mydic1 = new Dictionary<string, string>();
  }
}

DictionaryとKeyValuePair構造体

Dictionaryをforeachで扱うときは、KeyValuePair構造体でDictionaryの要素を順番に扱うことが可能です。以下は、そのコード断片です。

var sampleDic = new Dictionary<string, string>();
  sampleDic.Add("Kyoto", "Kyoto");
  sampleDic.Add("Mie", "Tsu");
  sampleDic.Add("Shimane", "Matsue");
}

foreach(KeyValuePair<string, string> dicItem in sampleDic) {
  Console.WriteLine("[{0}:{1}]", dicItem.Key, dicItem.Value);
}

Dictionaryの初期化

Dictionaryの初期化は、以下の2パターンどちらでも可能です。

【パターン1】
変数名 = new Dictionary<データ型1, データ型2>() { {key1, value1}, {key2, value2}, ... };
【パターン2】
変数名 = new Dictionary<データ型1, データ型2> { {key1, value1}, {key2, value2}, ... };

Dictionaryの宣言と初期化を合わせた実際のサンプルコードは、以下の通りです。

using System.Collections.Generic;

public class MyDic {
  public static void Main() {
    //インスタンス化のみ実行
    var mydic1 = new Dictionary<string, string>();

    //インスタンス化と初期化を同時に実行
    var mydic2 = new Dictionary<string, string>(){
      {"mykey1","value11"},
      {"mykey2","value12"},
      {"mykey3","value13"}
    };
  }
}

Dictionaryの基本的な使い方

Dictionaryの定義ができたら、次にDictionaryの基本的な操作方法をサンプルコードで示します。

Addで要素を追加

Dictionaryへ要素を追加するには、Addメソッドを使用します。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");
    }
  }
}

Dictionaryに同じキーをAddした場合の挙動

すでに、同じKeyがDictionaryにある場合、Addするとエラーになります。同じKeyを複数持てない点に注意してコードを作成しましょう。

foreachで要素を取得

Addメソッドで3要素を追加した状態で、foreachを使って要素を取得します。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    foreach(KeyValuePair<string, string> dicItem in sampleDic) {
      Console.WriteLine("[{0}:{1}]", dicItem.Key, dicItem.Value);
    }
    Console.ReadKey();
  }
}

上記の実行結果は、以下の通りです。

[Kyoto:Kyoto]
[Mie:Tsu]
[Shimane:Matsue]

KeyでValueを取得

Dictionaryは、Keyを使ってValueを簡単に取得できます。以下は、Keyに「Mie」を指定して、対となっているValueを取得する例です。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    string str = "Mie";
    Console.WriteLine("[{0}:{1}]", str, sampleDic[str]);
    Console.ReadKey();
  }
}

上記の実行結果は、以下の通りです。

[Mie:Tsu]

Mieと対応するValueである「Tsu」が取得できていることを確認できます。

Removeで要素を削除

要素の追加は、Addメソッドを使いましたが、要素を削除する場合はRemoveメソッドを使います。以下は、Removeメソッドを使うサンプルコードです。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    sampleDic.Remove("Mie");
    foreach(KeyValuePair<string, string> dicItem in sampleDic) {
      Console.WriteLine("[{0}:{1}]", dicItem.Key, dicItem.Value);
    }
    Console.ReadKey();
  }
}

上記の実行結果は、以下の通りです。

[Kyoto:Kyoto]
[Shimane:Matsue]

要素の存在を確認

指定のKeyがあるかどうかを確認するには、ContainsKeyメソッドを使用します。
ContainsKeyメソッドの戻り値は、真偽値です。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    if (sampleDic.ContainsKey("Shimane")){
      // "Shimane"はあるため存在しますと出力される
      Console.WriteLine("存在します");
    }

    if (sampleDic.ContainsKey("Osaka")){
      // "Osaka"はないため以下の行は実行されない
      Console.WriteLine("存在します");
    }
    Console.ReadKey();

  }
}

上記の実行結果は、以下の通りです。

存在します

指定のValueがあるかどうかは、ContainsValueメソッドを使用します。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    if (sampleDic.ContainsValue("Tsu")){
      // "Tsu"はあるため存在しますと出力される
      Console.WriteLine("存在します");
    }

    if (sampleDic.ContainsValue("Okayama")){
      // "Okayama"はないため以下の行は実行されない
      Console.WriteLine("存在します");
    }
    Console.ReadKey();

  }
}

上記の実行結果は、以下の通りです。

存在します

キー指定で値を更新

Key指定で値を更新する方法をサンプルコードで示します。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    sampleDic["Kyoto"] = "京都";
    foreach(KeyValuePair<string, string> dicItem in sampleDic) {
      Console.WriteLine("[{0}:{1}]", dicItem.Key, dicItem.Value);
    }
    Console.ReadKey();
  }
}

上記の実行結果は、以下の通りです。

[Kyoto:京都]
[Mie:Tsu]
[Shimane:Matsue]

要素に複数の値を持たせる方法

Dictionaryの要素に複数の値を持たせるには、Valueの部分をListにして持たせるといいでしょう。

Dictionary<TKey, List<TValue>> mDictionary = new Dictionary<TKey, List<TValue>>();

Dictionaryのコピー

Dictionaryのコピーを簡単に行うには、コピー先のDictionary宣言・定義時のコンストラクタの引数に、コピー元のオブジェクトを渡します。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    // コンストラクタの引数にsampleDic1を指定
    var sampleDic2 = new Dictionary<string, string>(sampleDic1);
    foreach(KeyValuePair<string, string> item in sampleDic2) {
      Console.WriteLine("[{0}:{1}]", item.Key, item.Value);
    }
    Console.ReadKey();
  }
};

sampleDic2には、sampleDic1の内容がコピーされ、実行結果は以下の通りとなります。

[Kyoto:Kyoto]
[Mie:Tsu]
[Shimane:Matsue]

要素をソート

Dictionaryの要素をソートするには、LINQを使う方法とKeyValuePair構造体のListを使う方法があります。以下は、LINQのOrderByメソッドの引数にラムダ式で記述してソートするサンプルコードです。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    // LINQのOrderByメソッドを使ってソート
    var newDic = sampleDic.OrderBy(x => x.Value);
    foreach(KeyValuePair<string, string> item in newDic) {
      Console.WriteLine("[{0}:{1}]", item.Key, item.Value);
    }
    Console.ReadKey();
  }
}

sampleDicの要素は、OrderByメソッドによりValueの昇順にソートされて以下の結果となります。

[Kyoto:Kyoto]
[Shimane:Matsue]
[Mie:Tsu]

KeyValuePairのListを使っても、Dictionaryの要素をソートすることが可能です。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    // KeyValuePair構造体を使ってListにする
    var list = new List<KeyValuePair<string, string>>(sampleDic);
    // ListをKeyの要素で逆順にソートする
    list.Sort((a, b) => b.Key.CompareTo(a.Key));
  
    foreach(var item in list) {
      Console.WriteLine("[{0}:{1}]", item.Key, item.Value);
    }
    Console.ReadKey();
  }
}

ListをKeyの要素で逆順にソートしたため、出力結果は以下の通りです。

[Shimane:Matsue]
[Mie:Tsu]
[Kyoto:Kyoto]

Listとの相互変換

DictionaryのKeyとValueをそれぞれListに変換すると便利な場合があります。また、2つのリストを1つのDictionaryに統合することもできます。サンプルコードは、以下の通りです。

using System;
using System.Collections.Generic;

class MyDic {
  static void Main() {
    var sampleDic = new Dictionary<string, string>();
      sampleDic.Add("Kyoto", "Kyoto");
      sampleDic.Add("Mie", "Tsu");
      sampleDic.Add("Shimane", "Matsue");

    // sampleDicのKeyリストとValueリストをListのコンストラクタに渡す
    var list1 = new List<string>(sampleDic.Keys);
    var list2 = new List<string>(sampleDic.Values);

    Console.WriteLine("[{0}]", string.Join(", ", list1 ));
    Console.WriteLine("[{0}]", string.Join(", ", list2 ));

    // list1とlist2をsampleDic2に変換
    Dictionary<string, string> sampleDic2 =
      list1.Zip(list2, (k, v) => new { k, v }).ToDictionary(a => a.k, a => a.v);

    foreach(KeyValuePair<string, string> item in sampleDic2) {
      Console.WriteLine("[{0}:{1}]", item.Key, item.Value);
    }
    Console.ReadKey();
  }
}

実行結果は、以下の通りです。

[Kyoto, Mie, Shimane]
[Kyoto, Tsu, Matsue]
[Kyoto:Kyoto]
[Mie:Tsu]
[Shimane:Matsue]

C#のDictionaryを使いこなそう

C#のDictionaryは、KeyとValueのセットを保持できる連想配列です。自作のプログラミングで使っていくうちに、使いどころや扱い方に慣れてくるので、自作のプログラムを多く書いて復習することで使いこなせるようになります。

AKKODiS別ウィンドウで開くでは、エンジニアの方向けにさまざまなサポートをしています。自習だけでは覚えにくい場合は、AKKODiS(派遣・紹介予定派遣)別ウィンドウで開くが提供するAKKODiS Academy別ウィンドウで開くのC#講座を受講するなど、オンライン講座なども活用しましょう。資格取得など、目標を掲げることでも学習のモチベーションはアップします。C#の資格については、関連記事「C#の資格とは?難易度や試験範囲について紹介」もあるので、ぜひ参考にしてください。

(2021年10月現在)

AKKODiSコンサルティングに関するお問い合わせ