How to make IEnumerable<string>.Contains case-insensitive?

.NetArraysStringLinq

.Net Problem Overview


Suppose I have a .net Array of strings.

string[] strings = new string[] { "AbC", "123", "Xyz", "321" };

If I wanted to see if the array of strings contains "ABC", I could write

strings.Contains("ABC");

However, suppose that I want a function that will return true if the uppercase values of the strings contain "ABC". I could uppercase the entire array, but it looks like the .Contains method has some overloads for specifying the comparison, but I'm confused by the syntax.

How can I use the IEnumerable<string>.Contains() method implement this logic?

.Net Solutions


Solution 1 - .Net

Use overloaded Enumerable.Contains method which accepts equality comparer:

strings.Contains("ABC", StringComparer.InvariantCultureIgnoreCase)

Also there is strings comparer in box which you can use.

Solution 2 - .Net

I personally like this guy's LambdaComparer, which is really useful for stuff like this:

LINQ Your Collections with IEqualityComparer and Lambda Expressions

Example Usage:

var comparer = new LambdaComparer<string>(
    (lhs, rhs) => lhs.Equals(rhs, StringComparison.InvariantCultureIgnoreCase));

var seq = new[]{"a","b","c","d","e"};

Debug.Assert(seq.Contains("A", comparer));

Solution 3 - .Net

If for some reason you either prefer or are forced to use StringComparison and not StringComparer, you can add an extension method as follows:

public static bool Contains(this IEnumerable<string> items, string value, StringComparison stringComparison)
{
    StringComparer stringComparer;

    switch (stringComparison)
    {
        case StringComparison.CurrentCulture:
            stringComparer = StringComparer.CurrentCulture;
            break;
        case StringComparison.CurrentCultureIgnoreCase:
            stringComparer = StringComparer.CurrentCultureIgnoreCase;
            break;
        case StringComparison.InvariantCulture:
            stringComparer = StringComparer.InvariantCulture;
            break;
        case StringComparison.InvariantCultureIgnoreCase:
            stringComparer = StringComparer.InvariantCultureIgnoreCase;
            break;
        case StringComparison.Ordinal:
            stringComparer = StringComparer.Ordinal;
            break;
        case StringComparison.OrdinalIgnoreCase:
            stringComparer = StringComparer.OrdinalIgnoreCase;
            break;
        default:
            throw new NotImplementedException();
    }

    return items.Contains(value, stringComparer);
}

More variations on how to map these can be found in this question.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVivian RiverView Question on Stackoverflow
Solution 1 - .NetSergey BerezovskiyView Answer on Stackoverflow
Solution 2 - .NetJerKimballView Answer on Stackoverflow
Solution 3 - .NetNate CookView Answer on Stackoverflow