开发者

Custom Inclusive TakeWhile(), is there a better way?

开发者 https://www.devze.com 2023-01-04 21:56 出处:网络
I\'ve written a custom LINQ extension method that extends the TakeWhile() method to be in开发者_JAVA百科clusive, rather than exclusive when the predicate is false.

I've written a custom LINQ extension method that extends the TakeWhile() method to be in开发者_JAVA百科clusive, rather than exclusive when the predicate is false.

        public static IEnumerable<T> TakeWhile<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool inclusive)
        {
            source.ThrowIfNull("source");
            predicate.ThrowIfNull("predicate");

            if (!inclusive)
                return source.TakeWhile(predicate);

            var totalCount = source.Count();
            var count = source.TakeWhile(predicate).Count();

            if (count == totalCount)
                return source;
            else
                return source.Take(count + 1);
        }

While this works, I'm sure there is a better way of doing it. I'm fairly sure that this doesn't work in terms of deferred execution/loading.

ThrowIfNull() is a extension method for ArgumentNullException checking

Can the community provide some some hints or re-writes? :)


You are correct; this is not friendly to deferred execution (calling Count requires a full enumeration of the source).

You could, however, do this:

public static IEnumerable<T> TakeWhile<T>(this IEnumerable<T> source, Func<T, bool> predicate, bool inclusive)
{
    foreach(T item in source)
    {
        if(predicate(item)) 
        {
            yield return item;
        }
        else
        {
            if(inclusive) yield return item;

            yield break;
        }
    }
} 


Тot a direct answer to the question. I want to show how you can use SkipWhile to simulate inclusive TakeWhile logic.

IEnumerable<string> list = new List<string> { "1", "2", "3", "4", "5" };
var result = list
    .Reverse()
    .SkipWhile(item => item != "3")
    .Reverse();
// result will be {"1", "2", "3"}

However note that doing it this way will be less efficient, because essentially, list in this case has to to be reversed twice. So make sure performance will not be an issue.

0

精彩评论

暂无评论...
验证码 换一张
取 消