Wilsonhut

Deal with it or don't

TakeAllButLast

[UPDATE: Newer TakeAllButLast!]
Linq provides us with the extension method First() to get the first item in an enumerable. It also gives us Take(x) to get the first x items. The provided Last() extension method has no “TakeAllButLast(x)” equivalent.

I wanted one, so I wrote it (with a conceptual tip provided by a coworker). It’s not trivial to do if you want to make sure that you only enumerate the list once.

public static IEnumerable<T> TakeAllButLast<T>(this IEnumerable<T> enumerable, int count)

{

  if (enumerable == null)

  {

    throw new ArgumentNullException(“enumerable”);

  }

  var enumerator = enumerable.GetEnumerator();

  if (count < 0)

  {

    throw new ArgumentException(“Parameter count can’t be negative.”, “count”);

  }

  var segment = enumerator.GetNext(count + 1);

  if (segment.Length <= count)

  {

    yield break;

  }

  for (var i = 0; ; i = (i + 1) % segment.Length)

  {

    yield return segment[i];

    if (!enumerator.MoveNext())

    {

      yield break;

    }

    segment[i] = enumerator.Current;

  }

}

private static T[] GetNext<T>(this IEnumerator<T> enumerator, int count)

{

  return Enumerable.Repeat(true, count)

    .Where(b => enumerator.MoveNext())

    .Select(b => enumerator.Current)

    .ToArray();

}

Notice, there’s also an extension method in there called GetNext on the Enumerator. Crazy!

Advertisements

3 responses to “TakeAllButLast

  1. Pingback: Obvious Extension Method: TakeAllButLast « Wilsonhut

  2. Tiffani February 5, 2013 at 7:31 pm

    Howdy would you mind letting me know which hosting
    company you’re using? I’ve loaded your blog in 3 completely different browsers and I must
    say this blog loads a lot faster then most. Can you recommend a good web hosting provider at
    a fair price? Thanks a lot, I appreciate it!

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: