Rob
Rob

Reputation: 7217

Fast multiple string compare

In c# is there a quick way to replace the following with more efficient code:

string letters = "a,b,c,d,e,f";

if (letters.Contains("a"))
{
    return true;
}

if (letters.Contains("b"))
{
    return true;
}

if (letters.Contains("c"))
{
    return true;
}

I want to do away with having to have three compare lines of code.

Thanks!

Upvotes: 0

Views: 3595

Answers (8)

Servy
Servy

Reputation: 203817

You can use Intersect to see if there are any characters in common between the two character sets. Note that strings implement IEnumerable<char>, so you can treat all strings as just sequences of characters.

bool result = "abc".Intersect(letters).Any();

Note that this solution, as it will put all of the characters from letters into a HashSet, will be dramatically more efficient than the other solutions currently posted that are performing multiple linear searches on the string, assuming the string is of a non-trivial size, and the search characters are not right near the start. (You did say efficiency mattered.)

Upvotes: 2

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174309

You could use something like this:

return letters.Any(c => c == 'a' || c == 'b' || c == 'c');

Or this:

var lettersToLookFor = "abc";
return letters.Any(c => lettersToLookFor.Contains(c));

As per the comments, the last line of the previous code block can be shortened further:

return letters.Any(lettersToLookFor.Contains);

Upvotes: 8

Adrian Thompson Phillips
Adrian Thompson Phillips

Reputation: 7141

You could use a regular expression, I couldn't vouch for the efficiency though, you'd have to run a comparison and get timings:

return Regex.IsMatch(letters, "[abc]");

Upvotes: 0

Soner G&#246;n&#252;l
Soner G&#246;n&#252;l

Reputation: 98750

How about using String.IndexOfAny(Char[]) method like?

string letters = "a,b,c,d,e,f";

if ((letters.IndexOfAny(new char[] { 'a', 'b', 'c' }) >= 0))
{
   return true;
}

The zero-based index position of the first occurrence in this instance where any character in anyOf was found; -1 if no character in anyOf was found.

Upvotes: 0

Hilmi
Hilmi

Reputation: 3441

var arr = new []{"a","b","c"};
letters.Any(m => arr.Contains(m))

Upvotes: 0

Binary Worrier
Binary Worrier

Reputation: 51711

If you're literally looking for single characters in a string you can use IndexOfAny

return letters.IndexOfAny('a', 'b', 'c') >= 0;

It makes one pass over the entire string and compares each char in the string against the chars passed in.

If none of the chars exist it's still M * N comparisons (same as 3 if's above), but if any char does exist it gets out of dodge faster.
Also for longer strings it's kinder on CPU cache memory.

Upvotes: 4

Maxime R.C
Maxime R.C

Reputation: 179

LINQ is the way to go.

return letters.Any(c => c == 'a' || c == 'b' || c == 'c');

Upvotes: 1

Rohit Vats
Rohit Vats

Reputation: 81243

Simplest solution would be to club three if in single statement or can use Any() like Daniel mentioned.

if (letters.Contains("a") || letters.Contains("b") || letters.Contains("c"))
{
    return true;
}

Upvotes: 1

Related Questions