Welcome to MSDN Blogs Sign in | Join | Help
The SkipLast Extension Method

[Blog Map] 

When writing queries, just as you sometimes want to skip the first n items in a collection, on occasion you want to skip the last n items.  You could certain count the items remaining in the collection, and use the Take operator to take all but the last, but this would mean iterating the collection twice, and would result in uglier code.  This post presents the SkipLast Extension method, which allows you to skip the last n items.

In the next post, I’m going to present an enhancement to LtxOpenXml classes, which use LINQ to XML to query Open XML documents, to allow you to write queries on tables within spreadsheet (XLSX) documents.  I needed SkipLast to implement this.

Here is the implementation of the extension method, and a couple of examples of its use:

using System;

using System.Collections.Generic;

using System.Collections.Specialized;

using System.Linq;

using System.Text;

 

public static class MyExtensions

{

    public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source,

        int count)

    {

        Queue<T> saveList = new Queue<T>();

        int saved = 0;

        foreach (T item in source)

        {

            if (saved < count)

            {

                saveList.Enqueue(item);

                ++saved;

                continue;

            }

            saveList.Enqueue(item);

            yield return saveList.Dequeue();

        }

        yield break;

    }

}

 

class Program

{

    static void Main(string[] args)

    {

        int[] a = new[] { 1, 2, 3, 4, 5 };

        var b = a.SkipLast(2);

        foreach (var item in b)

            Console.WriteLine(item);

 

        List<string> c = new List<string>() {

            "one", "two", "three", "four", "five"

        };

        var d = c.Skip(1).SkipLast(1);

        foreach (var e in d)

            Console.WriteLine(e);

    }

}

 

This example outputs:

1

2

3

two

three

four

 

Code is attached.

Posted: Friday, November 14, 2008 1:35 PM by EricWhite
Attachment(s): SkipLast.cs

Comments

Ben Lings said:

Would it be more appropriate to use a Queue<T>, rather than a List<T>?  The implementation would be

  Queue<T> saveList = new Queue<T>();

       int saved = 0;

       foreach (T item in source)

       {

           if (saved < count)

           {

               saveList.Add(item);

               ++saved;

               continue;

           }

           saveList.Enque(item);

           yield return saveList.Deque();

       }

       yield break;

# November 14, 2008 2:52 PM

EricWhite said:

Ben,

You are absolutely right, a Queue<T> is the better collection to use.  I've updated the post with a new implementation.

Thanks, Eric

# November 14, 2008 4:10 PM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Page view tracker