Paulo Morgado

.NET Development & Architecture

This Blog

Syndication

Search

Tags

News

Unit Test Today! Get Typemock Isolator!

Projects

Books

 

Visitors

Visitor Locations

Community

Email Notifications

Archives

Profile

Disclaimer

The opinions and viewpoints expressed in this site are mine and do not necessarily reflect those of Microsoft, my employer or any community that I belong to. Any code or opinions are offered as is. Products or services mentioned are purchased by me, made available to me by my employer or the manufacturer/vendor which doesn't influence my opinion in any way.

LINQ: Implementing The TakeLastWhile Operator
LINQ With C# (Portuguese)

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)

The implementation of the first method is very simple. We start with an empty buffer and buffer 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>();
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) CodePlex project for LINQ utilities and operators: PauloMorgado.Linq

Published Mon, Oct 18 2010 0:26 by Paulo Morgado

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above: