So while this sounds like an easy problem to solve, there is not a single-liner that accomplishes that in .NET (besides a RegEx which is an overkill in this case).
So the .NET BCL has the LastIndexOf and LastIndexOfAny method and its overloads, and it has methods in System.Char to identify if a character is categorized as a certain Unicode category, in this case IsWhiteSpace. But there is no good way to combine these two together. So I decided to implement my own way using an Extension Method.
What I wanted to do was this:
[TestFixture]
public class StringExtensionTests
{
[Test]
public void TestLastIndexWhere()
{
Assert.That("Hello".LastIndexWhere(x => x == 'l'), Is.EqualTo(3));
Assert.That("Hello".LastIndexWhere(x => x == 'x'), Is.EqualTo(-1));
Assert.That("Helloel".LastIndexWhere(x => x == 'l', 5), Is.EqualTo(3));
Assert.That("Helloel".LastIndexWhere(x => x == 'l', 5, 2), Is.EqualTo(-1));
Assert.That("Hello el".LastIndexWhere(x => char.IsWhiteSpace(x), 5, 2), Is.EqualTo(5));
Assert.That("Hello\tel".LastIndexWhere(x => char.IsWhiteSpace(x), 5, 2), Is.EqualTo(5));
}
}
I skipped the tests for Exceptions here.As you see this allows to use the whole set of possibilities to work with characters in an easy to use way. And this is the implementation:
public static class StringExtensions
{
public static int LastIndexWhere(this string str, Func<char, bool> condition)
{
return LastIndexWhere(str, condition, str.Length - 1, str.Length);
}
public static int LastIndexWhere(this string str, Func<char, bool> condition, int startIndex)
{
return LastIndexWhere(str, condition, startIndex, startIndex);
}
public static int LastIndexWhere(this string str, Func<char, bool> condition, int startIndex, int count)
{
if (str == null) throw new ArgumentNullException("str");
if (condition == null) throw new ArgumentNullException("condition");
if (startIndex >= str.Length) throw new ArgumentOutOfRangeException("startIndex");
if (startIndex - count < -1) throw new ArgumentOutOfRangeException("count");
for (int i = startIndex; i > startIndex - count; i--)
{
if (condition(str[i]))
{
return i;
}
}
return -1;
}
}
Quite easy, but comes in handy in this case.So I guess I include that in my Util library for the future.
No comments:
Post a Comment