65.9K
CodeProject is changing. Read more.
Home

LINQ: Implementing the TakeLastWhile Operator

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1 vote)

Oct 18, 2010

CPOL
viewsIcon

15779

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:

public static IEnumerable<TSource> TakeLastWhile<TSource>
(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
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:

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:

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:

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.