Borysław Bobulski
Borysław Bobulski

Reputation: 471

The fastest way to check if multiple substrings occurs at position

There is a function in .NET public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index);

Is there a simply way to use similar function to find out if substrings occurs at some position (index)?

I mean:

public static bool ElementAtPosContains(this string, int index, string[] valuesToCheck)
{ ... }


string test1 = "abcd5f";
string[] substrings = {"1" , "2", "3", "4", "5"};
if (test.ElementAtPosContains(4, substrings))
 {
    DoSomething();
 }

If there would be 1, 2, 3, 4, 5 at 4 position in string - return true. I can do this thing:

   public static bool ElementAtPosContains(this string inputStr, int index, string[] valuesToCheck)
   { 
     if (valuesToCheck == null)
       return false;

     foreach (string value in valuesToCheck)
     {
       if (inputStr.Substring(index, value.Length) == value)
         return true;
     }
     return false;
    }

But this seems to be not very effective

Upvotes: 2

Views: 577

Answers (2)

Ivan Golović
Ivan Golović

Reputation: 8832

Try with this:

    public static bool ElementAtPosContains(this string inputStr, int index, string[] valuesToCheck)
    {
        if (valuesToCheck == null || valuesToCheck.Length == 0 || inputStr.Length < index)
            return false;

        return valuesToCheck.Any(sub => string.CompareOrdinal(inputStr, index, sub, 0, sub.Length) == 0);
    }

CompareOrdinal comparisons are always case-sensitive and don't take culture into consideration. This makes them faster then usual Compare or = operator. If you don't need culture-aware comparison or case-insensitive comparison, this method should do the job faster since it compares numeric values of characters from the string.

Demo

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460148

This seems to be smarter:

public static bool ElementAtPosContains(this string inputStr, int index, IList<String> valuesToCheck)
{
    if (valuesToCheck == null || inputStr.Length < index)
        return false;

    return valuesToCheck.Any(s => s.Length + index <= inputStr.Length 
                             &&   inputStr.IndexOf(s, index) == index);
}

Demo

Although i think that you're doing premature optimization.

Upvotes: 1

Related Questions