有字符串吗?接受谓词的IndexOf
本文关键字:谓词 IndexOf 字符串 | 更新日期: 2023-09-27 18:08:40
我需要能够说出类似myString.IndexOf(c => !Char.IsDigit(c))
的东西,但我在。net框架中找不到任何这样的方法。我错过什么了吗?
下面的工作,但在这里滚动我自己的似乎有点乏味:
using System;
class Program
{
static void Main()
{
string text = "555ttt555";
int nonDigitIndex = text.IndexOf(c => !Char.IsDigit(c));
Console.WriteLine(nonDigitIndex);
}
}
static class StringExtensions
{
public static int IndexOf(this string self, Predicate<char> predicate)
{
for (int index = 0; index < self.Length; ++index) {
if (predicate(self[index])) {
return index;
}
}
return -1;
}
}
你不会错过任何东西。没有您在框架中搜索的方式的IndexOf
。不滚动你能做的最接近的事情是
text
.Select((c, index) => new { Char = c, Index = index })
.Where(pair => !Char.IsDigit(pair.Char))
.Select(pair => pair.Index)
.FirstOrDefault(-1);
然而,这并不容易遵循,并且会导致无意义的分配。在这种情况下,我更喜欢自己滚动IndexOf
。
编辑哦。忘记FirstOrDefault
是我在应用程序中手工滚动的函数,并且不是具有此过载的标准LINQ库的一部分。
public static T FirstOrDefault<T>(this IEnumerable<T> enumerable, T defaultValue) {
using (var enumerator = enmumerable.GetEnumerator()) {
if (enumerator.MoveNext()) {
return enumerator.Current;
}
return defaultValue;
}
这是一个没有任何自定义扩展的版本。注意,这只是举例,请不要把它放在你的应用程序;)
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();
你目前的解决方案是更好的,但是可以做一些像…
int c = myString.TakeWhile(c => Char.IsDigit(c)).Count();
return (c == myString.Length) ? -1 : c;
比这里的其他建议稍微短一些,并且稍微少一些异常情况,编辑以显示如何处理-1情况。注意,谓词与问题中的谓词相反,因为我们希望在找到非数字之前计算有多少字符是数字。
MSDN将显示给定类型的所有方法和扩展:MSDN字符串类
目前还没有专门针对String
的扩展方法来准确描述您所提供的内容。正如其他人所说,滚动自己的选项并不是一个坏的选择,因为其他选项(除了都没有那么优雅。regex
)
编辑我误解了使用RegEx
查找索引的效率…
Array.FindIndex()提供谓词重载,但仅适用于char[]。你可以将字符串转换为字符数组并使用array。查找索引如下:
Array.FindIndex( text.ToCharArray(), 0, c => Char.IsDigit( c ) )
性能损失应该很小,因为字符串可能存储在字符数组中。
由于String
是IEnumerable<char>
,您可以将扩展方法一般化,以相当容易地支持几乎任何类型的集合(包括字符串):
public static int IndexOf<T>(this IEnumerable<T> list, Predicate<T> predicate)
{
var index = 0;
foreach (var item in list)
{
if (predicate(item))
{
return index;
}
++index;
}
return -1;
}