potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C# Dictionaryでキーの大文字小文字を同一視する

本文

Dictionaryクラスはコンストラクタの引数に次のいずれかを与えることでキーの大文字小文字の区別を指定できます。区別の方法は与えた変数により異なります(リファレンス参照)。

  • StringComparer.OrdinalIgnoreCase
  • StringComparer.InvariantCultureIgnoreCase
  • StringComparer.CurrentCultureIgnoreCase

StringComparer.OrdinalIgnoreCaseによる具体的なコードは以下です。

トップレベステートメントC# 9)

using System;
using System.Collections.Generic;

var dict1 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
foreach (var x in new[] { "a", "A", "b", "b", "c" })
{
    if (!dict1.ContainsKey(x))
    {
        dict1.Add(x, 1);
    }
    else
    {
        dict1[x] += 1;
    }
}

foreach (var entry in dict1)
{
    Console.WriteLine(entry);
}
// [a, 2]←"a"と"A"が同一扱いされた。
// [b, 2]←"b"と"b"が同一扱いされた。
// [c, 1]

Main関数(C# 8)

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var dict1 = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
        foreach (var x in new[] { "a", "A", "b", "b", "c" })
        {
            if (!dict1.ContainsKey(x))
            {
                dict1.Add(x, 1);
            }
            else
            {
                dict1[x] += 1;
            }
        }
        foreach (var entry in dict1)
        {
            Console.WriteLine(entry);
        }
        // [a, 2]←"a"と"A"が同一扱いされた。
        // [b, 2]←"b"と"b"が同一扱いされた。
        // [c, 1]
    }
}

補足

  • DictionaryクラスのコンストラクタはStringComparer.OrdinalIgnoreCase等の他にもIEqualityComparer<T>インターフェイスを実装したクラスを受け取れます。同一視の方法をカスタマイズしたい場合、IEqualityComparer<string>インターフェイスを実装します。
  • ifブロック内のdict1.Add(x, 1);dict1.Add(x, 0);に変えればelseブロックの中身を外に出せるのですが、可読性のかわりに処理量が増えるのでそのままにしています。

参考