Tips: Seeing if a string is in a List/Array ignoring case and culture

So I recently came across an issue when using the LINQ contains method. I needed to see if an array/list of strings contained a string pulled from the database. This string was entered by a user so could in fact be in a different case but should still match.

The existing Contains method is great but does not come out of the box with an ignore case option.

Example of using Contains with Case sensitivity:


string[] myArrayOfStrings = { "Luke", "astringiwanttomatchon" };

// In this example, doesContain would equal false, which is not my desired outcome

bool doesContain = myArrayOfStrings.Contains("aStringIwantToMatchOn");

Now, there is a way around this. It requires using one of the override for the Contains method which takes an IEqualityComparer<string> implementation.

All you need to do is write your own implementation of the Interface and pass an instance of that class when doing your comparisons.

First, lets write our implementation:


public class IgnoreCaseEqualityComparer : IEqualityComparer<string>
{
#region Members

private const int _multiplier = 89;

#endregion

#region IEqualityComparer Implementation

public bool Equals(string x, string y)
{
if (x == null || y == null)
return false;

// This line is the key, we are ignoring the case and culture when doing the comparison

return x.Equals(y, StringComparison.InvariantCultureIgnoreCase);
}

// This method simply needs to return a unique hashcode/identifier for each item in the string list

public int GetHashCode(string obj)
{
int hashCode = 0;

// Fault value for empty strings
if (String.IsNullOrEmpty(obj))
return hashCode;

// Get length to determine first and last chars
char firstLetter = obj.First();
char lastLetter = obj.Last();

// Compute hash code from two characters
int part1 = firstLetter + obj.Length;
hashCode = (_multiplier * part1) + lastLetter + obj.Length;

return hashCode;
}

#endregion
}

OK, now just need to use our implementation to get case and culture insensitive Contains checking.

Using our class:


string[] myArrayOfStrings = { "Luke", "astringiwanttomatchon" };

// Now doesContains will be true!! Woohoo!

bool doesContain = myArrayOfStrings.Contains("aStringIwantToMatchOn", new IgnoreCaseEqualityComparer());

 

Here is a code snippet of my IgnoreCaseEqualityComparer class: https://bitbucket.org/snippets/lukejkw/aKjAE

Ask below if you have any questions.
Luke

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s