Wilsonhut

Deal with it or don't

Obvious Extension Method: TakeAllButLast

I had a previous post about TakeAllButLast, but here’s a more succinct version which also has a callback for the untaken records.

Basically, Linq provides us with the extension method Take(x) to get the first x items in an enumerable. It also gives us Skip(x) to take all but the first x items. There is no “TakeAllButLast(x)” or “SkipLast(x)” equivalent.

public static class EnumerableExtensions
{
    public static IEnumerable<T> TakeAllButLast<T>(this IEnumerable<T> items, int count, Action<T> onUntaken = null)
    {
        if (items == null)
            throw new ArgumentNullException("items");

        if (count < 0)
            throw new ArgumentOutOfRangeException("count");

        var buffer = new Queue<T>(count + 1);

        foreach (var item in items)
        {
            buffer.Enqueue(item);

            if (buffer.Count == count + 1)
            {
                yield return buffer.Dequeue();
            }
        }
        if (onUntaken != null)
        {
            foreach (var x in buffer)
            {
                onUntaken(x);
            }
        }
    }
}

 

You’d use this like this example where you’re processing a file that has ONE Trailer record:

using (var reader = new StreamReader(_inputFile))
{
    var fileLines = reader.GetLines().TakeAllButLast(1);
}

…which also uses my GetLines method for a TextReader.

And now, with the callback, you can take a peek at the last line that it skipped:

using (var reader = new StreamReader(_inputFile))
{
    string lastLine;
    var fileLines = reader.GetLines().TakeAllButLast(1, line => lastLine = line);
}
Advertisements

One response to “Obvious Extension Method: TakeAllButLast

  1. Pingback: TakeAllButLast « Wilsonhut

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: