Alex Rivera | Logout

Linq: The "opposite" of Take?

Asked 2012-04-20T14:02:39.947
15

Using Linq; how can I do the "opposite" of Take?

I.e. instead of getting the first n elements such as in

aCollection.Take(n)

I want to get everything but the last n elements. Something like

aCollection.Leave(n)

(Don't ask why :-)

Edit

I suppose I can do it this way aCollection.TakeWhile((x, index) => index < aCollection.Count - n) Or in the form of an extension

public static IEnumerable<TSource> Leave<TSource>(this IEnumerable<TSource> source, int n) 
{ 
  return source.TakeWhile((x, index) => index < source.Count() - n); 
}

But in the case of Linq to SQL or NHibernate Linq it would have been nice if the generated SQL took care of it and generated something like (for SQL Server/T-SQL)

SELECT TOP(SELECT COUNT(*) -@n FROM ATable) * FROM ATable Or some other more clever SQL implementation.

I suppose there is nothing like it? (But the edit was actually not part of the question.)

Edit
Report

1 Answer

1

This will be much more efficient than the solutions with a double-reverse, since it creates only one list and only enumerates the list once.

public static class Extensions
{
   static IEnumerable<T> Leave<T>(this IEnumerable<T> items, int numToSkip)
   {
      var list = items.ToList();
      // Assert numToSkip <= list count.
      list.RemoveRange(list.Count - numToSkip, numToSkip);
      return List
   }
}


string alphabet = "abcdefghijklmnopqrstuvwxyz";
var chars = alphabet.Leave(10); // abcdefghijklmnop
answered 2012-04-20T14:15:54.490

Your Answer