4

I have a case insensitive dictionary in asp.net/vb.net like this:

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

it holds values like this

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

I want that if a user tries to find a value like this:

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

he gets 100 but right now it gets exception because dictionary keys don't have hyphon '-'. Which method do i need to override.

please suggest

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
DotnetSparrow
  • 27,428
  • 62
  • 183
  • 316

2 Answers2

3

You have to create a custom IEqualityComparer.

something like this:

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();
    }
}

then use that class in the dictionary: Dictionary x = new Dictionary(new MyEqualityComparer())

Douglas
  • 36,802
  • 9
  • 76
  • 89
1

You could either add ONE-hundred,100 as well to the dictionary(the easiest approach) or build a custom 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

testing

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")
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • I've upvoted the other answer because it doesn't repeat the `.Replace("-", " ")` code, even though a VB answer makes more sense to a VB question. – Douglas May 31 '12 at 08:23
  • @Douglas: the other answer does not work since it replaces with empty string instead of white-space. – Tim Schmelter May 31 '12 at 08:28
  • 1
    Good point, fixed. (Since it was DRY, the fix was on just one line, http://c2.com/cgi/wiki?DontRepeatYourself ) – Douglas May 31 '12 at 08:51