転職を繰り返したサラリーマンの多趣味ブログ

30才未経験でSEに転職した人の多趣味ブログ

【技術書メモ】C#プログラミングのイディオム / 定石&パターン⑦

今回はディクショナリの操作について。ディクショナリと聞くと馴染みがないが、JavaでいうMapと認識している。

ディクショナリの基本操作

ディクショナリの初期化。

var flowerDict = new Dictionary<string, int>() {
    {"sunflower", 400},
    {"pansy", 300},
};


なお、ディクショナリにはオブジェクトも値に格納できる。

var employeeDict = new Dictionary<int, Employee> {
    {100, new Employee(100, "やまだ") },
};


では、続いて各操作を確認していく。
まずは、要素の追加から。

flowerDict["violet"] = 600;

// Addメソッドを使う場合
flowerDict.Add("violet", 600);


要素を取り出す。

int price = flowerDict["rose"];


指定したキーにディクショナリが存在しない場合は、例外が発生してしまう。
そのため、ディクショナリにキーが存在しているか調べることができる。

var key = "pansy";
if (flowerDict.ContainsKey(key)) {
}


ディクショナリから要素を削除する。

var result = flowerDict.Remove("pansy");


ディクショナリからすべての要素を取り出す。
foreach文を使うことになるが、foreachで取り出せる要素の型は、KeyValuePair型。
Keyプロパティでキーの値、Valueプロパティで対応する値を参照する。

foreach (var item in flowerDict)
    Console.WriteLine("{0} = {1}", item.Key, item.Value);


では、ディクショナリからすべてのキーを取り出す方法をみてみる。

foreach (var key in flowerDict.Keys)

ディクショナリの応用

配列やリストをディクショナリに変換する。

var employeeDict = employees.ToDictionary(emp => emp.Code);


ディクショナリから別のディクショナリを作成する。
ディクショナリからある条件に一致したものだけを抜き出し、新たにディクショナリを生成するなどの場合に用いられる。

var newDict = flowerDict.Where(x => x.Value >= 400).ToDictionary(flower => flower.Key, flower => flower.Value);


カスタマクラスをキーにする。
文字列や数値ではなく、独自に作成したカスタムクラスも、ディクショナリーのキーにできる。
ただ、これには一つだけ注意が必要で、キーに使用するカスタムクラスに、EqualsメソッドとGetHashCodeメソッドをオーバーライドする必要がある。

public int Day { get; private set; }

public int Month { get; private set; }

public MonthDay(int month, int day) {
    this.Month = month;
    this.Day = day;
}

public override bool Equals(object obj) {

    var other = obj as MonthDay;
    if (other == null)
        throw new ArgumentException();
    return this.Day == other.Day && this.Month == other.Month;

}

public override int GetHashCode() {
    return Month.GetHashCode() * 31 + Day.GetHashCode();
}
public static void Main(string[] args)
{

    var dict = new Dictionary<MonthDay, string> {
        {new MonthDay(3, 5), "珊瑚の日" },
        {new MonthDay(8, 4), "箸の日" },
        {new MonthDay(10, 3), "登山の日" },
    };

    var md = new MonthDay(8, 4);
    var s = dict[md];
    Console.WriteLine(s);
}


ディクショナリを使う際、キーがディクショナリに格納されていることが重要で、その値を利用しないケースがある。
こういった場合は、HashSetクラスを使用する。

var hash = new HashSet<string>();
hash.Add("string");
hash.OrderBy();


ディクショナリは、キーの重複を許していない。そのため、同一キーで複数のオブジェクトを関連づけることができない。
こういう場合は、値をリスト型にしておく。

var dict = new Dictionary<string, List<string>() {
    { "PC", new List<string> {"パーソナルコンピュータ", "プログラムカウンタ",}},
}