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 SkipLastWhile Operator
LINQ Com C#

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

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

public static IEnumerable<TSource> SkipLastWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
public static IEnumerable<TSource> SkipLastWhile<TSource>(this IEnumerable<TSource> source, Func<TSource, int, bool> predicate)

The implementation of these methods 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, all buffered items are yield, the buffer is cleared and the the item that doesn’t satisfy the criteria is yield:

var buffer = new List<TSource>();

foreach (var item in source)
{
    if (predicate(item))
    {
        buffer.Add(item);
    }
    else
    {
        if (buffer.Count > 0)
        {
            foreach (var bufferedItem in buffer)
            {
                yield return bufferedItem;
            }

            buffer.Clear();
        }

        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
    {
        if (buffer.Count > 0)
        {
            foreach (var bufferedItem in buffer)
            {
                yield return bufferedItem;
            }

            buffer.Clear();
        }

        yield return item;
    }
}

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

Published Wed, Oct 20 2010 1:00 by Paulo Morgado

Comments

# re: LINQ: Implementing The SkipLastWhile Operator@ Wednesday, December 15, 2010 7:19 AM

Hello Mr. Morgado,

I have read a question of you in msdn about an issue with Linq and VS2k8...

I am getting the memory access violation error:

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Thread information:

   Thread ID: 5

   Thread account name: IIS APPPOOL\OpenSpanServerAppPool

   Is impersonating: False

   Stack trace:    at System.Linq.Enumerable.WhereEnumerableIterator`1.Select[TResult](Func`2 selector)

  at System.Linq.Enumerable.Select[TSource,TResult](IEnumerable`1 source, Func`2 selector)

  at System.Web.Mvc.MvcHandler.RemoveOptionalRoutingParameters()

  at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)

  at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)

  at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)

  at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)

  at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

  at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

I am using NHibernate an my site is hosted in IIS with its own pool , DB is SQL Server 2005 sp3.

Did you see something related to this issue?

Alberto

# re: LINQ: Implementing The SkipLastWhile Operator@ Thursday, December 16, 2010 5:22 AM

If I recall it correctly, it was due to a Visual Studio add-in. Running outside Visual Studio (thus, not using the add-in) worked fine.

Are you having this problem just running from Visual Studio, or always?

Paulo Morgado

# re: LINQ: Implementing The SkipLastWhile Operator@ Tuesday, January 04, 2011 11:46 AM

I found in my case that it was due to having the TypeMock Isolator add-in without a license. Disabling the add-in(s) and restarting VS solved my problems.

Phil

# re: LINQ: Implementing The SkipLastWhile Operator@ Tuesday, January 04, 2011 5:12 PM

I kind of was leaning myself towards TypeMock. But I have a valide license, though.

Paulo Morgado

Leave a Comment

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