Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetEnumerator() in the middle of a string

Tags:

c#

linq

Suppose I have a very long string, and would like to get an enumerator (for LINQ goodness) that begins in the middle of the string, at a given index. That is,

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

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

// Use LINQ.
enumerator.TakeWhile( /* ... */ );

is there a better (ie: cheaper/faster) way to do this?

like image 597
arturo Avatar asked Dec 08 '22 02:12

arturo


2 Answers

Consider Enumerable.Skip:

longString.Skip(9999).TakeWhile( /* ... */ );

However, keep in mind that as Michael Liu wrote, Skip works in iterative way (strictly speaking it depends on implementation, but at least this is what you usually have, see e.g. .NET Framework 4.6 Reference Sources). If it causes measurable1 slowness in your case, look at Michael's extension method.


  1. D.Knuth: "premature optimization is the root of all evil "
like image 152
AlexD Avatar answered Dec 10 '22 16:12

AlexD


Using longString.Skip(n), as in AlexD's answer, will make n calls to the underlying enumerator's MoveNext method to skip past all the characters you don't care about. For large values of n, you can improve performance by writing a custom iterator method:

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

Sample usage:

longString.EnumerableSubstring(9999).TakeWhile( /* ... */ )
like image 21
Michael Liu Avatar answered Dec 10 '22 14:12

Michael Liu