70

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?

Vivian River
  • 31,198
  • 62
  • 198
  • 313
  • 2
    Let me emphasize that I know that I can write `strings.select(s => s.ToUpper).Contains("ABC")`, but I'd like to know if it's possible using `.Contains` without uppercasing the array. – Vivian River Feb 08 '13 at 21:49
  • 1
    Nor should you change any casing because of [The turkish i Problem](http://haacked.com/archive/2012/07/05/turkish-i-problem-and-why-you-should-care.aspx/). – Erik Philips Apr 17 '17 at 00:28

3 Answers3

143

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.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
2

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));
JerKimball
  • 16,584
  • 3
  • 43
  • 55
1

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.

Nate Cook
  • 8,395
  • 5
  • 46
  • 37