【问题标题】:Ignoring hyphen in case insensitive dictionary keys忽略不区分大小写的字典键中的连字符
【发布时间】:2012-05-31 07:57:20
【问题描述】:

我在 asp.net/vb.net 中有一个不区分大小写的字典,如下所示:

Dim caseInsensitiveDictionary = New Dictionary(Of String, Single)(StringComparer.OrdinalIgnoreCase)

它拥有这样的值

one hundred, 100
one hundred one, 101
one hundred two, 102

如果用户试图找到这样的值,我希望这样:

Response.Write(dictionary("ONE-hundred").ToString)

他得到了 100,但现在它得到了异常,因为字典键没有连字符“-”。我需要重写哪个方法。

请推荐

【问题讨论】:

  • 你为什么不简单地添加ONE-hundred,100呢?
  • 这是否意味着我需要为每个数字添加两个键?一百一百换一百?
  • 还有四把钥匙代表一百一(或者一百一或者一百一或者一百一……)(其实最后一个有点牵强)

标签: c# asp.net vb.net


【解决方案1】:

您必须创建一个自定义的 IEqualityComparer。

类似这样的:

public class MyEqualityComparer : IEqualityComparer<string>
{
    public bool Equals(string x, string y)
    {
        return FixString(x).Equals(FixString(y), StringComparison.InvariantCultureIgnoreCase);
    }

    private string FixString(string x)
    {
        // replace hyphens
        return x.Replace("-", " ");
    }

    public int GetHashCode(string obj)
    {
        return FixString(obj).GetHashCode();
    }
}

然后在字典中使用该类: 字典 x = new Dictionary(new MyEqualityComparer())

【讨论】:

  • 和我要写的差不多,但是把InvariantCultureIgnoreCase改成OrdinalIgnoreCase
  • @Rawling InvariantCultureIgnoreCase 和 OrdinalIgoneCase 有什么区别?
  • @DotnetSparrow 我之所以发表此评论,是因为您在自己的代码中使用了 Ordinal 而不是 InvariantCulture - 我自己也不是 100% 确定差异。
  • 好的,谢谢。我收到声明预期错误:IEqualityComparer
  • 对,应该换成“”。道格拉斯已经修好了。谢谢。
【解决方案2】:

您可以将ONE-hundred,100 也添加到字典中(最简单的方法)或构建自定义StringComparer

Class CaseInsensitiveIgnoringStringComparer
    Inherits StringComparer
    Private caseInsentiveComparer As System.StringComparer = StringComparer.OrdinalIgnoreCase
    Public Property IgnoreList As IList(Of String) = Nothing
    Public Property ReplaceWith As String = " "

    Private Function Replace(original As String) As String
        If IgnoreList Is Nothing OrElse IgnoreList.Count = 0 Then
            Return original
        Else
            For Each s As String In IgnoreList
                original = original.Replace(s, ReplaceWith)
            Next
            Return original
        End If
    End Function

    Public Overloads Overrides Function Compare(x As String, y As String) As Integer
        Return caseInsentiveComparer.Compare(Replace(x), Replace(y))
    End Function

    Public Overloads Overrides Function Equals(x As String, y As String) As Boolean
        Return caseInsentiveComparer.Equals(Replace(x), Replace(y))
    End Function

    Public Overloads Overrides Function GetHashCode(obj As String) As Integer
        Return caseInsentiveComparer.GetHashCode(Replace(obj))
    End Function
End Class

测试

Dim comp = New CaseInsensitiveIgnoringStringComparer() With {.IgnoreList = {"-", "+"}, .ReplaceWith = " "}
Dim caseInsensitiveDictionary = New Dictionary(Of String, Single)(comp)
caseInsensitiveDictionary.Add("One hundred", 100)
caseInsensitiveDictionary.Add("One hundred one", 101)
caseInsensitiveDictionary.Add("One hundred two", 102)

' normally following both lines would cause exceptions '
Dim n100 = caseInsensitiveDictionary("ONE-hundred")
n100 = caseInsensitiveDictionary("oNE+Hundred")

【讨论】:

  • 我赞成另一个答案,因为它不会重复 .Replace("-", " ") 代码,即使 VB 答案对 VB 问题更有意义。
  • @Douglas:另一个答案不起作用,因为它替换为空字符串而不是空格。
  • 好点,已修复。 (因为它是 DRY,所以修复只在一行上,c2.com/cgi/wiki?DontRepeatYourself
猜你喜欢
  • 2012-09-11
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 2018-12-30
  • 2020-02-18
  • 1970-01-01
相关资源
最近更新 更多