GetEnumerator()在一个字符串的中间

art*_*uro 4 c# linq

假设我有一个非常长的字符串,并希望得到一个枚举器(对于LINQ良好),它在字符串的中间开始,在给定的索引处.那是,

var longString = GetLongString();
var index = 99999;

// seems unnecessarily expensive to allocate a new string
var enumerator = longString.Substring(9999).GetEnumerator();

// Use LINQ.
enumerator.TakeWhile( /* ... */ );
Run Code Online (Sandbox Code Playgroud)

有没有更好的(即:更便宜/更快)的方式来做到这一点?

Ale*_*exD 9

考虑Enumerable.Skip:

longString.Skip(9999).TakeWhile( /* ... */ );
Run Code Online (Sandbox Code Playgroud)

但是,请记住,正如Michael Liu所写,Skip以迭代方式工作(严格来说,它取决于实现,但至少这是您通常所拥有的,请参阅.NET Framework 4.6 Reference Sources).如果它在你的情况下导致可测量的1缓慢,请查看迈克尔的扩展方法.


  1. D.Knuth:" 过早优化是万恶之源 "


Mic*_*Liu 5

使用longString.Skip(n),如AlexD的回答,会令ñ调用底层的枚举的MoveNext方法跳过你不关心的所有字符.对于较大的n值,可以通过编写自定义迭代器方法来提高性能:

public static IEnumerable<char> EnumerableSubstring(this string s, int startIndex)
{
    for (; startIndex < s.Length; startIndex++)
        yield return s[startIndex];
}
Run Code Online (Sandbox Code Playgroud)

样品用法:

longString.EnumerableSubstring(9999).TakeWhile( /* ... */ )
Run Code Online (Sandbox Code Playgroud)