说我有一个IEnumerable.例如,{2,1,42,0,9,6,5,3,8}.
我需要获得与谓词匹配的项目的"运行".例如,如果我的谓词是
bool isSmallerThanSix(int number){...}
Run Code Online (Sandbox Code Playgroud)
我想获得以下输出:{{2,1},{0},{5,3}}
是否有内置功能可以实现这一目标?
到目前为止我有这个:
public static IEnumerable<IEnumerable<T>> GetSequences<T>(this IEnumerable<T> source,
Func<T, bool> selector) {
if (source == null || selector == null) {
yield break;
}
IEnumerable<T> 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));
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来很有效,但是我是在半夜写的,因此从星期二开始就效率低十五.是否有更好的,最好是内置(因此经过良好测试)的方式?
非常感谢你们的时间,
利雅.
据我所知,没有一种构建方法.但是,Count在an上调用扩展方法IEnumerable效率不高,因为它必须枚举列表以获取计数.因此,我想出了具有相同效果的这一点.
public static IEnumerable<IEnumerable<T>>
GetSequences<T>(this IEnumerable<T> source, Func<T, bool> selector)
{
// omitted null checks for brevity
var list = new List<T>();
foreach(var item in source)
{
if (selector.Invoke(item))
{
list.Add(item);
}
else if (list.Count > 0)
{
yield return list;
list = new List<T>();
}
}
if (list.Count > 0)
yield return list;
}
Run Code Online (Sandbox Code Playgroud)
正如Jon Skeet所提到的那样,在这种情况下使用SkipWhile和TakeWhile看起来效率也很低,因为它们会在迭代器上的迭代器上创建迭代器.您可以在调试示例时将其检查出来,当您逐步尝试查找下一个序列时会有点疯狂,即使示例很简单也是如此.
| 归档时间: |
|
| 查看次数: |
313 次 |
| 最近记录: |