说我有一个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)); } }
这看起来很有效,但是我是在半夜写的,因此从星期二开始就效率低十五.是否有更好的,最好是内置(因此经过良好测试)的方式?
非常感谢你们的时间,
利雅.
据我所知,没有一种构建方法.但是,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所提到的那样,在这种情况下使用SkipWhile
和TakeWhile
看起来效率也很低,因为它们会在迭代器上的迭代器上创建迭代器.您可以在调试示例时将其检查出来,当您逐步尝试查找下一个序列时会有点疯狂,即使示例很简单也是如此.