当前位置:  开发笔记 > 编程语言 > 正文

是否有更好的方法来获取每个项与谓词匹配的子序列?

如何解决《是否有更好的方法来获取每个项与谓词匹配的子序列?》经验,为你挑选了1个好方法。

说我有一个IEnumerable.例如,{2,1,42,0,9,6,5,3,8}.

我需要获得与谓词匹配的项目的"运行".例如,如果我的谓词是

bool isSmallerThanSix(int number){...}

我想获得以下输出:{{2,1},{0},{5,3}}

是否有内置功能可以实现这一目标?

到目前为止我有这个:

public static IEnumerable> GetSequences(this IEnumerable source,
      Func selector) {

        if (source == null || selector == null) {
            yield break;
        }

        IEnumerable rest = source.SkipWhile(obj => !selector(obj));

        while (rest.Count() > 0) {
            yield return rest.TakeWhile(obj => selector(obj));
            rest = rest
                    .SkipWhile(obj => selector(obj))
                    .SkipWhile(obj => !selector(obj));
        }


    }

这看起来很有效,但是我是在半夜写的,因此从星期二开始就效率低十五.是否有更好的,最好是内置(因此经过良好测试)的方式?

非常感谢你们的时间,

利雅.



1> Garry Shutle..:

据我所知,没有一种构建方法.但是,Count在an上调用扩展方法IEnumerable效率不高,因为它必须枚举列表以获取计数.因此,我想出了具有相同效果的这一点.

public static IEnumerable> 
    GetSequences(this IEnumerable source, Func selector)
{
    // omitted null checks for brevity
    var list = new List();

    foreach(var item in source)
    {
        if (selector.Invoke(item))
        {
            list.Add(item);
        }
        else if (list.Count > 0)
        {
            yield return list;
            list = new List();
        }
    }

    if (list.Count > 0)
        yield return list;
}

正如Jon Skeet所提到的那样,在这种情况下使用SkipWhileTakeWhile看起来效率也很低,因为它们会在迭代器上的迭代器上创建迭代器.您可以在调试示例时将其检查出来,当您逐步尝试查找下一个序列时会有点疯狂,即使示例很简单也是如此.

推荐阅读
TXCWB_523
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有