首页 文章

通用字典的不区分大小写的访问

提问于
浏览
182

我有一个使用托管dll的应用程序 . 其中一个dll返回一个通用字典:

Dictionary<string, int> MyDictionary;

字典包含大小写的键 .

另一方面,我得到一个潜在的密钥列表(字符串),但我不能保证这种情况 . 我试图使用键获取字典中的值 . 但是,由于案件不匹配,以下情况当然会失败:

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

我希望TryGetValue会有一个像_1329397中提到的忽略大小写标志,但似乎这对通用字典无效 .

有没有办法让字典的值忽略关键案例?有没有比使用正确的StringComparer.OrdinalIgnoreCase参数创建字典的新副本更好的解决方法?

3 回答

  • 376

    在尝试获取值时,无法指定 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);
    

    然后,此字典使用 StringComparer.OrdinalIgnoreCase 上的 GetHashCode() 实现,以便 comparer.GetHashCode("foo")comparer.GetHashcode("FOO") 为您提供相同的值 .

    或者,如果字典中只有少数元素,和/或您只需要查找一次或两次,您可以将原始字典视为 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(n)而不是O(1) .

  • 10

    对于那些从不使用常规字典构造函数的LINQers:

    myCollection.ToDictionary(x => x.PartNumber, x => x.PartDescription, StringComparer.OrdinalIgnoreCase)
    
  • 17

    它不是很优雅,但万一你不能改变字典的创建,你需要的只是一个肮脏的黑客,这个怎么样:

    var item = MyDictionary.Where(x => x.Key.ToLower() == MyIndex.ToLower()).FirstOrDefault();
        if (item != null)
        {
            TheValue = item.Value;
        }
    

相关问题