C#でキーとバリューで値を管理するDictionaryを使う方法

プログラミングを行っていく中で、何かしらの目印と値を同時に持ちたいという場合がよくあります。例えば学校のクラスでいうと「出席番号(学籍番号)」と「名前」のようなものです。C#ではそのような目印と値をセットにして保有できる機能として「Dictionary」が用意されています

Dictionaryを知っておくことで、「出席番号(学籍番号)」と「名前」のような構造体が簡単に作成できます。この記事ではC#のDictionaryをサンプルコードも交えて解説していきます。Dictionaryは知っておくと随所で便利に使えるので知っておきましょう。

Dictionaryの基礎知識

Dictionaryは前回のタプルと同様に2つの値を同時に持つことが可能な構造体の一種で、自由に型を設定できる識別子と値のペアを複数持てる型のようなものになります。Microsoftの公式ドキュメントでは以下のようになっています。

キーと値のコレクションを表します。

Dictionary | Microsoft Docs

コレクションは「リスト」のような意味だと思っていてください。要するに複数持つことができる、という型の総称になります。「キーと値」というのは、先ほどにも挙げた「識別子」と「値」という意味です。

識別子と値がセットになっているものを「キーバリュー」と言ったりもします。学校のクラスの例でいうと、出席番号と名前と同様なイメージです。Dictionaryに追加できるのは、「キーが他と被っていないもの」になります。「キー(識別子)が他と被らない」というのを「一意」や「ユニーク」と言いますので覚えておきましょう。

Dictionaryは以下のような形式で初期化して使用します。以下の例ではキーにint型を使用し、バリューにstring型を使用するDictionaryを宣言します。

Dictionary<int, string> _dic = new Dictionary<int, string>();

それでは実際にコードを書きながらDictionaryの基本的な使い方を解説していきます。

Dictionaryを使う方法

それではDictionaryの使い方をサンプルコードを交えて解説していきます。新規のコンソールアプリケーションを作成して、以下のコードを記述して実行させてみてください。

using System;
using System.Collections.Generic;

namespace App27
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, string> students = new Dictionary<int, string>();

            //データを設定する
            students.Add(1, "Smith");
            students.Add(2, "John");
            students.Add(3, "Maria");

            //2番を取り出す
            string name = students[2];
            Console.WriteLine("取り出した値:" + name);
            Console.WriteLine();

            //前から取り出す
            foreach(KeyValuePair<int, string> student in students)
            {
                Console.Write("キー:" + student.Key.ToString() + " ");
                Console.WriteLine("バリュー:" + student.Value.ToString());
            }
            Console.ReadLine();
        }
    }
}

上記のソースコードの実行結果は以下のようになっていると思います。

取り出した値:John

キー:1 バリュー:Smith
キー:2 バリュー:John
キー:3 バリュー:Maria

上記のような実行結果になっていれば大丈夫になりますので、上記のサンプルコードからDictionaryの使い方を解説してきます。

Dictionaryを使う方法

これまでの変数と同様にDictionaryを使用する場合は宣言をして初期化をする必要があります。そのためにはクラスで解説した時と同様にインスタンス化を行う必要があります。

Dictionary<int, string> students = new Dictionary<int, string>();

上記の箇所がまさにそうです。ここではint型とstring型でDictionaryを使用する宣言をしています。Dictionaryでは左側がキーで右側がバリューの型になります。キーとバリューは好きな型で宣言できるので、必要に応じて使い分けるようにしてください。

バリューを設定する方法

インスタンス化したDictionaryに値を設定していくには、Addメソッドを使用することで可能となります。今回は学校と同じように出席番号と名前のイメージにしてみました。

//データを設定する
students.Add(1, "Smith");
students.Add(2, "John");
students.Add(3, "Maria");

Addメソッドでは第一引数がキーで第二引数がバリューになります。1番がSmith、2番がJohn・・・としています。値を設定するときは「Addメソッド」を使用しましょう。その時はキーとバリューを同時に設定します。

値を取り出す方法

Dictionaryから値を取り出すには2通りの方法があります。キーを指定して取得する方法とすべての要素を順番に取り出していく方法です。

//2番を取り出す
string name = students[2];

キーを指定して値を取得する場合は、Dictionaryの変数名に”[キー]”で取得することができます。このサンプルではキーに2が割り振られているバリューを取得するようにしています。

//前から取り出す
foreach(KeyValuePair<int, string> student in students)
{
    Console.Write("キー:" + student.Key.ToString() + " ");
    Console.WriteLine("バリュー:" + student.Value.ToString());
}

値をすべて取得する場合は「foreach」との相性が抜群です。各要素を反映させるにはKeyValuePairでDictionaryのキーとバリューに対応する型を記述すると便利です。キーの要素を使用する場合は「Key」、バリューを使用する場合は「Value」にアクセスすれば値を取得できます。

Dictionaryを使うメリット

タプルとDictionaryにおいて、どうしてDictionaryを使うべきなのかという話をしたいと思います。Dictionaryを使う主な理由は要素へのアクセスが早いという点です。Dictionaryは重複を許さない一意のキーによって値が管理されているので、特定の要素の検索が早くなります。

タプルなどでもキーとバリューのように使用することは可能ですが、重複を許さないという制約はありません。そのため要素の検索が遅くなる可能性があります。

例えば一般的にも同姓同名がたくさんいたら探すのは大変ですよね。住所や年齢など付随情報との付け合わせをして本人を特定する必要があります。その点、例えば出席番号で識別子が与えられていた場合は、同姓同名であっても生徒の特定は早いです。

これと同じような現象がプログラミングでも起こるということです。一意のキーを持つということは、検索スピードが上がるということで、これはアプリケーションの性能にも良い影響を与えるのです。