在C#中是否有一个懒惰的`String.Split`

Wil*_*sem 13 c# string ienumerable enumerator lazy-evaluation

所有string.Split方法似乎都返回一个字符串数组(string[]).

我想知道是否有一个惰性变体返回一个IEnumerable<string>大字符串(或无限长度IEnumerable<char>),当一个人只对第一个子序列感兴趣时,一个节省计算工作量和内存.如果字符串由设备/程序(网络,终端,管道)构成,并且因此不需要立即完全可用,则它也可能是有用的.这样人们就已经可以处理第一次出现了.

.NET框架中是否有这样的方法?

Ste*_*ers 5

您可以轻松地编写一个:

public static class StringExtensions
{
    public static IEnumerable<string> Split(this string toSplit, params char[] splits)
    {
        if (string.IsNullOrEmpty(toSplit))
            yield break;

        StringBuilder sb = new StringBuilder();

        foreach (var c in toSplit)
        {
            if (splits.Contains(c))
            {
                yield return sb.ToString();
                sb.Clear();
            }
            else
            {
                sb.Append(c);
            }
        }

        if (sb.Length > 0)
            yield return sb.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,我尚未使用string.split对它进行奇偶校验测试,但我认为它应该可以正常工作。

正如Servy指出的那样,这不会在字符串上分开。这不是那么简单,也不是那么有效,但是基本上是相同的模式。

public static IEnumerable<string> Split(this string toSplit, string[] separators)
{
    if (string.IsNullOrEmpty(toSplit))
        yield break;

    StringBuilder sb = new StringBuilder();
    foreach (var c in toSplit)
    {
        var s = sb.ToString();
        var sep = separators.FirstOrDefault(i => s.Contains(i));
        if (sep != null)
        {
            yield return s.Replace(sep, string.Empty);
            sb.Clear();
        }
        else
        {
            sb.Append(c);
        }
    }

    if (sb.Length > 0)
        yield return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)


usr*_*usr 4

没有内置这样的东西。Regex.Matches如果我正确解释反编译的代码,就是懒惰。也许你可以利用它。

或者,您只需编写自己的 split 函数。

实际上,您可以将大多数string函数想象为推广到任意序列。通常,甚至是序列T,而不仅仅是char。BCL 根本没有强调这一点。没有Enumerable.Subsequence例子。