汎用辞書の大文字と小文字を区別しないアクセス 質問する

汎用辞書の大文字と小文字を区別しないアクセス 質問する

マネージド DLL を使用するアプリケーションがあります。これらの DLL の 1 つは汎用辞書を返します。

Dictionary<string, int> MyDictionary;  

辞書には大文字と小文字のキーが含まれています。

一方、潜在的なキー (文字列) のリストを取得していますが、大文字と小文字は保証できません。キーを使用して辞書内の値を取得しようとしています。ただし、大文字と小文字が一致しないため、次のコードは失敗します。

bool Success = MyDictionary.TryGetValue( MyIndex, out TheValue );  

TryGetValueに、大文字と小文字を無視するフラグがあることを期待していました。MSDNドキュメントただし、これは一般的な辞書には当てはまらないようです。

キーの大文字と小文字を無視して辞書の値を取得する方法はありますか? 適切なStringComparer.OrdinalIgnoreCaseパラメータを使用して辞書の新しいコピーを作成するよりも良い回避策はありますか?

ベストアンサー1

StringComparer値を取得しようとする時点で を指定する方法はありません。デフォルトでは"foo".GetHashCode()と は"FOO".GetHashCode()まったく無関係であるため、大文字と小文字を区別するハッシュ マップで大文字と小文字を区別しない get を実装する合理的な方法はありません。アイテムは、(大文字と小文字を区別する) ハッシュコードに基づいてすでに保存されています。

ただし、次のようにすれば、最初から大文字と小文字を区別しない辞書を作成できます。

var comparer = StringComparer.OrdinalIgnoreCase;
var caseInsensitiveDictionary = new Dictionary<string, int>(comparer);

または、既存の大文字と小文字を区別する辞書の内容を使用して、大文字と小文字を区別しない新しい辞書を作成します (大文字と小文字の衝突がないことが確実な場合)。

var oldDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var newDictionary = new Dictionary<string, int>(oldDictionary, comparer);

これらの辞書はsoGetHashCode()の実装を使用し、同じ値を返します。StringComparer.OrdinalIgnoreCasecomparer.GetHashCode("foo")comparer.GetHashcode("FOO")

あるいは、辞書に要素が少数しかなく、1 回か 2 回しか検索する必要がない場合は、元の辞書を として扱い、IEnumerable<KeyValuePair<TKey, TValue>>それを反復処理することもできます。

var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var value = myDictionary.FirstOrDefault(x => String.Equals(x.Key, myKey, comparer)).Value;

または、LINQ を使わずに次の操作を行うこともできます:

var myKey = ...;
var myDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
int? value;
foreach (var element in myDictionary)
{
  if (String.Equals(element.Key, myKey, comparer))
  {
    value = element.Value;
    break;
  }
}

これにより、新しいデータ構造を作成するコストが節約されますが、その代わりに、検索のコストは O(1) ではなく O(n) になります。

おすすめ記事