Click here to Skip to main content
15,887,135 members
Articles / Programming Languages / C# 4.0

LINQ: Implementing the TakeLastWhile Operator

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
19 Oct 2010CPOL 15.1K   4   5
The TakeLastWhile operator returns last contiguous elements from a sequence that satisfy the specified criteria and is implemented as the TakeLastWhile extension methods.

free hit counters

Following my last posts (>)(>), in this post, I'll introduce the implementation of the TakeLastWhile operator.

The TakeLastWhile operator returns last contiguous elements from a sequence that satisfy the specified criteria and is implemented as the TakeLastWhile extension methods:

C#
public static IEnumerable<TSource> TakeLastWhile<TSource>
(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
C#
public static IEnumerable<TSource> TakeLastWhile<TSource>
(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)

What this method does, is even simpler. We start with an empty buffer and every item that satisfies the criteria implemented by a predicate. Whenever an item doesn't satisfy the criteria, the buffer is cleared:

C#
var buffer = new List<TSource>();

foreach (var item in source)
{
    if (predicate(item))
    {
        buffer.Add(item);
    }
    else
    {
        buffer.Clear();
    }
}

After traversing the source sequence, we just yield all the items, if any, in the buffer:

C#
foreach (var item in buffer)
{
    yield return item;
}

The overload that takes in account the index of the item only differs in the call the predicate that implements the criteria:

C#
var buffer = >new >List<TSource>();v
var idx = 0;

foreach (>var item >in source)
{
    if (predicate(item, idx++))
    {
        buffer.Add(item);
    }
    >else
    {
        buffer.Clear();
    }
}

foreach (var item in buffer)
{
    yield return item;
}

You can find the complete implementation of this operator (and more) in the CodePlex project for LINQ utilities and operators: PauloMorgado.Linq.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Paulo Morgado
Portugal Portugal

Comments and Discussions

 
GeneralBetter performance Pin
Magnus_18-Nov-10 3:51
Magnus_18-Nov-10 3:51 
GeneralRe: Better performance Pin
Paulo Morgado21-Nov-10 14:18
professionalPaulo Morgado21-Nov-10 14:18 
GeneralRe: Better performance [modified] Pin
Magnus_1-Dec-10 4:13
Magnus_1-Dec-10 4:13 
GeneralRe: Better performance Pin
Paulo Morgado1-Dec-10 13:43
professionalPaulo Morgado1-Dec-10 13:43 
Hi Maguns,


Partenon wrote:
its just storing references to objects.


Not if the element type is a value type.

Partenon wrote:
Also in your implementation you can skip the last loop and just return the buffer.


I did that in the first implementation, but then changed it because I didn't feel comfortable exposing a List<T> instead of an IEnumerbale<T>. Sometimes I'm a bit paranoid.

I'm thinking o building a custom collection that autogrows and clearing just resets the pointer to the last item. Pretty much like List<T> but take out everything that's not needed.
Cheers,

Paulo Morgado

Portugal - Europe's West Coast

Generalthanks. Pin
lxxsumi822-Oct-10 17:09
lxxsumi822-Oct-10 17:09 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.