Quantcast
Channel: Brian Pedersen's Sitecore and .NET Blog » LINQ
Viewing all articles
Browse latest Browse all 2

Simple string keyword search using ExtensionMethods and LINQ

$
0
0

This is a case I ran into recently. I need to create a multiple OR condition with LINQ. I have a list of user names and I wish to create a simple search where I can match any first name/middle name/last name combination with any of the names in my list. The search “Brian Pedersen” should match any combination such as ”Brian Jensen”, “Brian Steen Pedersen”, “Johan Pedersen” and “Brian Pedersen”.

This can be achieved very simply using LINQ. I need to split my search term into single words and use the Any LINQ statement:

// Remember to include LINQ
using System.Linq;

// This is the string to search within
string userName = "Brian Steen Pedersen";
// This is the search string
string searchString = "Brian Pedersen";
// I split the search string into indiviual words
string[] searchTerms = seachString.Split(' ');
// ... and return TRUE if any of the words is found inside the userName string
bool found = searchTerms.Any(searchTerm => userName.ToLower().Contains(searchTerm.ToLower()));

All I have to do is to put the code into a function and I can call this function whenever I need it:

public bool ContainsAny(string userName, IEnumerable<string> searchTerms)
{
  return searchTerms.Any(searchTerm => userName.ToLower().Contains(searchTerm.ToLower()));
}

Now, wouldn’t it be nice if the “ContainsAny” was a function of the String object? The String object Contains function only returns true for any exact match, and that’s not what I want. I want my ContainsAny function.

The String object can be extended using an Extension Method. Extension methods enable you to add methods to existing types without creating or modifying the original type. Read more about extension methods here.

This is 2 extension methods, extending the String object with ContainsAny and ContainsAll:

public static class StringExtension
{
  public static bool ContainsAny(this string str, IEnumerable<string> searchTerms)
  {
    return searchTerms.Any(searchTerm => str.ToLower().Contains(searchTerm.ToLower()));
  }  

  public static bool ContainsAll(this string str, IEnumerable<string> searchTerms)
  {
    return searchTerms.All(searchTerm => str.ToLower().Contains(searchTerm.ToLower()));
  }
}

With this code I can now use ContainsAny directly on the String object:

string userName = "Brian Steen Pedersen";
string searchString = "Brian Pedersen";

bool found = userName.ContainsAny(searchString.Split(' '));

I can even combine it with other LINQ statements. Lets assume that my users is stored in a generic List<string>. I can now find all users with this line of code:

// This is my fictive list of all users
List<string> allUsers = UserRepository.GetAllusers();
// This is my search string
string searchString = "Brian Pedersen";
// Here is all my users that match any words in the search string
List<string> foundUsers = allUsers.FindAll(s => s.ContainsAny(searchString.Split(' ')));


Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles





Latest Images