Is there a String.IndexOf that takes a predicate?
Your current solution is better but could do something like ...
int c = myString.TakeWhile(c => Char.IsDigit(c)).Count();
return (c == myString.Length) ? -1 : c;
Slightly shorter and somewhat fewer exception cases than the other proposals here, edited to show how to handle -1 case. Note that the predicate is the inverse of the predicate in the question because we want to count how many characters ARE digits before we find a non-digit.
MSDN will show you all methods and extensions for a given type: MSDN String Class
There is not currently an extension method specifically for String
describing exactly what you have provided. As others have stated, rolling your own is not a bad choice since other options (besides are not near as elegant.regex
)
Edit I was mistaken about the efficiency of using RegEx
to find indexes...
You're not missing anything. There is no IndexOf
in the manner you're searching for in the framework. The closest thing you could do without rolling your own would be
text
.Select((c, index) => new { Char = c, Index = index })
.Where(pair => !Char.IsDigit(pair.Char))
.Select(pair => pair.Index)
.FirstOrDefault(-1);
However that is not easy to follow and causes senseless allocations. I'd much prefer to roll my own IndexOf
in this case.
EDIT Whoops. Forgot that FirstOrDefault
is a function I have hand rolled in my apps and is not a part of the standard LINQ libraries with this overload.
public static T FirstOrDefault<T>(this IEnumerable<T> enumerable, T defaultValue) {
using (var enumerator = enmumerable.GetEnumerator()) {
if (enumerator.MoveNext()) {
return enumerator.Current;
}
return defaultValue;
}
Here is a version that works without any custom extensions. Note this is for example only, please don't put this in your app ;)
text
.Select((c, index) => new { Char = c, Index = index })
.Where(pair => !Char.IsDigit(pair.Char))
.Select(pair => pair.Index)
.Concat(Enumerable.Repeat(-1, 1))
.First();