【问题标题】:How to use HashSet<string>.Contains() method in case -insensitive mode?如何在不区分大小写的模式下使用 HashSet<string>.Contains() 方法?
【发布时间】:2011-02-09 16:35:46
【问题描述】:

不区分大小写模式下如何使用HashSet&lt;string&gt;.Contains()方法?

【问题讨论】:

  • 一个侧节点:当创建一个“正常”HashSet&lt;string&gt;(区分大小写)时,不可能创建一个高效的contains 方法。这是因为元素的哈希值是在添加到HashSet 时创建的。在内部,contains 方法检查哈希是否有效。不可能(有效地)将现有的哈希形式“区分大小写”转换为“不区分大小写”。

标签: c# string hashset


【解决方案1】:

您可以使用自定义比较器创建HashSet

HashSet<string> hs = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

hs.Add("Hello");

Console.WriteLine(hs.Contains("HeLLo"));

【讨论】:

  • +1 因为您使用Ordinal 而不是InvariantCulture。 .NET 指南建议我们在大多数情况下不要使用InvariantCulture(请参阅:msdn.microsoft.com/en-us/library/ms973919.aspx)。
  • CurrentCultureIgnoreCase 通常是更好的选择。
  • mdsdn 说:使用 StringComparison.Ordinal 或 OrdinalIgnoreCase 进行比较,作为与文化无关的字符串匹配的安全默认值。
  • 我相信 CurrentCultureIgnoreCase 将无法通过“土耳其测试”。如果当前文化是土耳其,“LIST”和“list”将无法匹配,因为该文化中“I”的小写字母不是“i”,而是“ı”没有点。因此,如果您期望 "LIST" == "list" 您会感到失望,如果当前文化是土耳其,那么这将返回 false。如果您要比较的字符串不是用户语言中的字符串,即如果它们是某种与用户语言无关的字符串,则使用 InvariantCultureIgnoreCase
  • 无法编辑,但 OrdinalIgnoreCase 通常比 InvariantCultureIgnoreCase 更受欢迎。我只是想指出为什么 CurrentCultureIgnoreCase 可能不适用(但取决于它是否是与用户语言相关的字符串)。
【解决方案2】:

你需要用正确的IEqualityComparer创建它:

HashSet<string> hashset = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);

【讨论】:

    【解决方案3】:

    这里没有必要,正如其他答案所证明的那样,但在其他不使用字符串的情况下,您可以选择实现IEqualityComparer&lt;T&gt;,然后您可以使用.Contains 重载。这是一个使用字符串的示例(同样,其他答案表明已经有一个可以满足您需求的字符串比较器)。 IEnumerable&lt;T&gt; 周围的许多方法都有接受此类比较器的重载,因此最好学习如何实现它们。

    class CustomStringComparer : IEqualityComparer<string>
    {
        public bool Equals(string x, string y)
        {
            return x.Equals(y, StringComparison.InvariantCultureIgnoreCase);
        }
    
        public int GetHashCode(string obj)
        {
            return obj.GetHashCode();
        }
    }
    

    然后使用它

    bool contains = hash.Contains("foo", new CustomStringComparer());
    

    【讨论】:

      【解决方案4】:

      您应该使用constructor,它允许您指定要使用的IEqualityComparer

      HashSet<String> hashSet = new HashSet<String>(StringComparer.InvariantCultureIgnoreCase);
      

      StringComparer 对象提供了一些常用的比较器作为静态属性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-08-16
        • 2013-05-11
        • 1970-01-01
        • 2013-12-04
        • 2011-03-08
        • 2019-04-19
        • 1970-01-01
        相关资源
        最近更新 更多