Case-Insensitive List Search

I have a list testList that contains a bunch of strings. I would like to add a new string into the testList only if it doesn’t already exist in the list. Therefore, I need to do a case-insensitive search of the list and make it efficient. I can’t use Contains because that doesn’t take into account the casing. I also don’t want to use ToUpper/ToLower for performance reasons. I came across this method, which works:

    if(testList.FindAll(x => x.IndexOf(keyword, 
                       StringComparison.OrdinalIgnoreCase) >= 0).Count > 0)
       Console.WriteLine("Found in list");

This works, but it also matches partial words. If the list contains “goat”, I can’t add “oat” because it claims that “oat” is already in the list. Is there a way to efficiently search lists in a case insensitive manner, where words have to match exactly? thanks

Turn exif_imagetype into caseinsensitive?

How can i make this exif_imagetype() function into caseinsensitive? so that it will allow both .jpg and .JPG ? cant figure this one out.. ive tried with stripos(); with no luck.. Here’s my code: $all

Case Insensitive search with $in

Is their any way to search a column in a collection in mongodb with $in which includes an array of elements for search and also caseInsensitive matching of those elements in the column ?

Riak Search JSON list

I wonder how you can search in Riak Search for list items. e.g.: { name: Zombies Eat Brains, tags: [zombies, funny, lol] } search-cmd search objects ???

PHP Zend Lucene make search “accent-insensitive” as in “case-insensitive”

So I am making a search engine for a site using Zend_Search_Lucene I am currently using Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive which works fine, except for one thing: it make

SharePoint List Search

I have a list with numerous Items. I want to search for a term in the List and have the ability to select the Item in which the search term exists. Thanks in advance for your help.

List Index Search

I have a List item List<string> xmlValue = new List<string>(); In this I have Item {English,Spanish,French,Hindi,English,English} I need to search all English item along with

Android search list, String

Hey guys what is the best way to search through my list of objects, they return a few strings, last name and first name for example. Here how i’m currently searching but my search needs to match the e

Prolog search list

In the code below, I am trying to search through a list and print match if there’s a match in the list and print no match if there’s no match. My code prints match if there’s a match but, doesn’

Binary search for List

Hello I need some help in my library. I’m trying to implement a binary search from my List<> but its not working so well. This is my Library class. private class Library { List<object> li

Python – list search

How can i rewrite this program so i get all the data.txt to a list and so i can search after city and get time and local to that city using list objects and attributes? Data.txt City1 Time1 Local1 —

Answers

Instead of String.IndexOf, use String.Equals to ensure you don’t have partial matches. Also don’t use FindAll as that goes through every element, use FindIndex (it stops on the first one it hits).

if(testList.FindIndex(x => x.Equals(keyword,  
    StringComparison.OrdinalIgnoreCase) ) != -1) 
    Console.WriteLine("Found in list"); 

Alternately use some LINQ methods (which also stops on the first one it hits)

if( testList.Any( s => s.Equals(keyword, StringComparison.OrdinalIgnoreCase) ) )
    Console.WriteLine("found in list");

You’re checking if the result of IndexOf is larger or equal 0, meaning whether the match starts anywhere in the string. Try checking if it’s equal to 0:

if (testList.FindAll(x => x.IndexOf(keyword, 
                   StringComparison.OrdinalIgnoreCase) >= 0).Count > 0)
   Console.WriteLine("Found in list");

Now “goat” and “oat” won’t match, but “goat” and “goa” will. To avoid this, you can compare the lenghts of the two strings.

To avoid all this complication, you can use a dictionary instead of a list. They key would be the lowercase string, and the value would be the real string. This way, performance isn’t hurt because you don’t have to use ToLower for each comparison, but you can still use Contains.

Based on Adam Sills answer above – here’s a nice clean extensions method for Contains… 🙂

///----------------------------------------------------------------------
/// <summary>
/// Determines whether the specified list contains the matching string value
/// </summary>
/// <param name="list">The list.</param>
/// <param name="value">The value to match.</param>
/// <param name="ignoreCase">if set to <c>true</c> the case is ignored.</param>
/// <returns>
///   <c>true</c> if the specified list contais the matching string; otherwise, <c>false</c>.
/// </returns>
///----------------------------------------------------------------------
public static bool Contains(this List<string> list, string value, bool ignoreCase = false)
{
    return ignoreCase ?
        list.Any(s => s.Equals(value, StringComparison.OrdinalIgnoreCase)) :
        list.Contains(value);
}

I had a similar problem, I needed the index of the item but it had to be case insensitive, i looked around the web for a few minutes and found nothing, so I just wrote a small method to get it done, here is what I did:

private static int getCaseInvariantIndex(List<string> ItemsList, string searchItem)
{
    List<string> lowercaselist = new List<string>();

    foreach (string item in ItemsList)
    {
        lowercaselist.Add(item.ToLower());
    }

    return lowercaselist.IndexOf(searchItem.ToLower());
}

Add this code to the same file, and call it like this:

int index = getCaseInvariantIndexFromList(ListOfItems, itemToFind);

Hope this helps, good luck!

I realise this is an old post, but just in case anyone else is looking, you can use Contains by providing the case insensitive string equality comparer like so:

if (testList.Contains(keyword, StringComparer.OrdinalIgnoreCase))
{
    Console.WriteLine("Keyword Exists");
}

This has been available since .net 2.0 according to msdn.

Based on Lance Larsen answer – here’s an extension method with the recommended string.Compare instead of string.Equals

It is highly recommended that you use an overload of String.Compare that takes a StringComparison parameter. Not only do these overloads allow you to define the exact comparison behavior you intended, using them will also make your code more readable for other developers. [Josh Free @ BCL Team Blog]

public static bool Contains(this List<string> source, string toCheck, StringComparison comp)
{
    return
       source != null &&
       !string.IsNullOrEmpty(toCheck) &&
       source.Any(x => string.Compare(x, toCheck, comp) == 0);
}