有没有更好的办法让每个项目一个谓词匹配子序列? [英] Is there a better way to get sub-sequences where each item matches a predicate?

查看:82
本文介绍了有没有更好的办法让每个项目一个谓词匹配子序列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Say I have an IEnumerable. For example, {2,1,42,0,9,6,5,3,8}.

我需要得到匹配的项目的运行谓词。例如,如果我的谓词

I need to get "runs" of items that match a predicate. For example, if my predicate was

bool isSmallerThanSix(int number){...}

我希望得到以下的输出:
{{2,1},{0},{5,3} }

I would want to get the following output: {{2,1},{0},{5,3}}

是否有实现这一内置功能

Is there a built-in function that accomplishes this?

到目前为止,我有这样的:

So far I have this:

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));
		}


	}



这似乎工作,但在半夜从周二从而效率低下15的方式是我写的。有没有更好的,最好是内置的(因此良好测试)的方式?

which seems to work, but was written by me in the middle of the night and thus inefficient fifteen ways from Tuesday. Is there a better, preferably built-in (and therefore well-tested) way?

感谢你们这么多的时间,

Thank y'all so much for your time,

河口。

推荐答案

有没有方法构建据我所知。然而,在调用计数上的扩展方法的IEnumerable 不是很有效,因为它有枚举列表来获得计数。所以,我想出了这一点,有同样的效果。

There is not a build in method as far as I'm aware. However, calling the Count extension method on an IEnumerable isn't very efficient as it has to enumerate the list to get the count. Therefore, I've come up with this that has the same effect.

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;
}



由于乔恩斯基特提到的,使用 SkipWhile TakeWhile 似乎也在这种情况下非常低效,因为他们将在迭代后,迭代器创建迭代器。你可以看看这个调试例如它会有点疯狂,当你踩通过它试图寻找下一个序列等,即使例子很简单的。

As Jon Skeet mentioned, the use of SkipWhile and TakeWhile also seem pretty inefficient in this case as they will create iterator upon iterator upon iterator. You can check this out as when debugging your example it goes a bit crazy as you step through it trying to find the next sequence and so on even though the example is simple.

这篇关于有没有更好的办法让每个项目一个谓词匹配子序列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆