67

Let us say I have this code

string seachKeyword = "";
List<string> sl = new List<string>();
sl.Add("store");
sl.Add("State");
sl.Add("STAMP");
sl.Add("Crawl");
sl.Add("Crow");
List<string> searchResults = sl.FindAll(s => s.Contains(seachKeyword));

How can I ignore the letter case in Contains search?

Thanks,

Mark
  • 695
  • 1
  • 6
  • 5

12 Answers12

88

Use Linq, this adds a new method to .Compare

using System.Linq;
using System.Collections.Generic;

List<string> MyList = new List<string>();
MyList.Add(...)
if (MyList.Contains(TestString, StringComparer.CurrentCultureIgnoreCase)) {
    //found
} 

so presumably

using System.Linq;
...

List<string> searchResults = sl.FindAll(s => s.Contains(seachKeyword, StringComparer.CurrentCultureIgnoreCase));  
CestLaGalere
  • 2,909
  • 1
  • 20
  • 20
  • 4
    Aha! I was using StringComparison on mistake! Thanks! – Steve's a D May 26 '14 at 12:19
  • Just a note: this won't work for - search a word in a text scenario because contains will search for complete text. Of course that isn't a scenario in the question and your answer works perfectly. :) – Ankur-m Oct 07 '15 at 08:40
  • 1
    @Ankur-m you probably want a Regex for that. Now you have 2 problems. – CAD bloke Oct 21 '15 at 03:40
  • @CADbloke I got it working without Regex. See my comment in this post: [Check if a string within a list contains a specific string with Linq](http://stackoverflow.com/questions/9032655/check-if-a-string-within-a-list-contains-a-specific-string-with-linq/9032686?noredirect=1#comment54058589_9032686) – Ankur-m Oct 21 '15 at 06:51
  • Ah, handy to know Linq adds that. – Nyerguds Sep 23 '16 at 08:39
66

The best option would be using the ordinal case-insensitive comparison, however the Contains method does not support it.

You can use the following to do this:

sl.FindAll(s => s.IndexOf(searchKeyword, StringComparison.OrdinalIgnoreCase) >= 0);

It would be better to wrap this in an extension method, such as:

public static bool Contains(this string target, string value, StringComparison comparison)
{
    return target.IndexOf(value, comparison) >= 0;
}

So you could use:

sl.FindAll(s => s.Contains(searchKeyword, StringComparison.OrdinalIgnoreCase));
Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
  • 3
    Wouldn't this mean that given the list in the OP's question, that `sl.FindAll(s => s.Contains("stat", StringComparison.OrdinalIgnoreCase));` would return `true`? While conceivable correct, I'd prefer a Contains on `List` that only returns true if the length of both strings are equal, regardless of case rather that one that returns true if the `List` contains a string that contains the search parameter. So ... `return target.IndexOf(value, comparison) >= 0 && target.Length == value.Length;` – GCymbala Jan 14 '15 at 20:31
  • +2 if I could. Exactly what I needed – Kieran Quinn Jul 20 '15 at 16:15
28

You CAN use Contains by providing the case-insensitive string equality comparer like so:

if (myList.Contains(keyword, StringComparer.OrdinalIgnoreCase))
{
    Console.WriteLine("Keyword Exists");
}
GorvGoyl
  • 42,508
  • 29
  • 229
  • 225
7
StringComparer.CurrentCultureIgnoreCase is a better approach instead of using indexOf.
Kunal Goel
  • 3,357
  • 1
  • 14
  • 20
6

The optimal solution will be to ignore the case when performing the comparison

List<string> searchResults = sl.FindAll(s => s.IndexOf(seachKeyword, System.StringComparison.OrdinalIgnoreCase) >= 0);
Petar Petrov
  • 2,729
  • 2
  • 22
  • 17
1

Below method will search your needed keyword and insert all searched items into a new list and then returns new list.

private List<string> serchForElement(string searchText, list<string> ListOfitems)
{            
    searchText = searchText.ToLower();
    List<string> Newlist = (from items in ListOfitems
                         where items.ToLower().Contains(searchText.ToLower())
                         select items).ToList<string>(); 

return Newlist; }

1

In the latest support we can have similar condition checked in LINQ even much more simple and elegant

using System.Linq

var strToCompare = "Hello";
bool match = myList.Any(x => string.Compare(x, strToCompare, StringComparison.OrdinalIgnoreCase) == 0);
Devesh
  • 4,500
  • 1
  • 17
  • 28
0

You can apply little trick over this.
Change all the string to same case: either upper or lower case

List searchResults = sl.FindAll(s => s.ToUpper().Contains(seachKeyword.ToUpper()));

Dipitak
  • 97
  • 1
  • 1
  • 3
0

For those of you having problems with searching through a LIST of LISTS, I found a solution.

In this example I am searching though a Jagged List and grabbing only the Lists that have the first string matching the argument.

List<List<string>> TEMPList = new List<List<string>>();

TEMPList = JaggedList.FindAll(str => str[0].ToLower().Contains(arg.ToLower()));

DoSomething(TEMPList);
0

The FindAll does enumeration of the entire list.

the better approach would be to break after finding the first instance.

bool found = list.FirstOrDefault(x=>String.Equals(x, searchKeyWord, Stringcomparison.OrdinalIgnoreCase) != null;

savagepanda
  • 857
  • 12
  • 25
0

Simply, you can use LINQ query as like below,

String str = "StackOverflow";
int IsExist = Mylist.Where( a => a.item.toLower() == str.toLower()).Count()
if(IsExist > 0)
{
     //Found
}
Jitendra G2
  • 1,196
  • 7
  • 14
-1

One of possible (may not be the best), is you lowercase all of the strings put into sl. Then you lowercase the searchKeyword.

Another solution is writing another method that lowercase 2 string parameters and compares them

vodkhang
  • 18,639
  • 11
  • 76
  • 110