Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq: The "opposite" of Take?

Tags:

c#

linq

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.)

like image 765
Ulf Åkerstedt Avatar asked Apr 20 '12 14:04

Ulf Åkerstedt


People also ask

What is take in Linq?

The Take operator is used to return a given number of elements from an array and the Skip operator skips over a specified number of elements from an array. Skip, skips elements up to a specified position starting from the first element in a sequence.

How to use Skip in linq C#?

C# Linq Skip() MethodSkip elements and return the remaining elements using the Skip() method. The following is an array. int[] marks = { 80, 55, 79, 99 }; Now, let us skip 2 elements using Lambda Expressions, but this is done after arranging the elements in descending order.

What the Skipwhile method does?

This method tests each element of source by using predicate and skips the element if the result is true . After the predicate function returns false for an element, that element and the remaining elements in source are yielded and there are no more invocations of predicate .

What is take Method C#?

C# Queryable Take() MethodGet specified number of elements from the beginning using the Take() method. The following is our array. int[] marks = { 35, 72, 50, 90, 95, 85, 52, 67 }; Now, use OrderByDescending to order the elements in Descending order. Then use the Take() method to get the elements.


2 Answers

aCollection.Take(aCollection.Count() - n);

EDIT: Just as a piece of interesting information which came up in the comments - you may think that the IEnumerable's extension method .Count() is slow, because it would iterate through all elements. But in case the actual object implements ICollection or ICollection<T>, it will just use the .Count property which should be O(1). So performance will not suffer in that case.

You can see the source code of IEnumerable.Count() at TypeDescriptor.net.

like image 127
Dmytro Shevchenko Avatar answered Sep 22 '22 04:09

Dmytro Shevchenko


I'm pretty sure there's no built-in method for this, but this can be done easily by chaining Reverse and Skip:

aCollection.Reverse().Skip(n).Reverse()
like image 36
Heinzi Avatar answered Sep 24 '22 04:09

Heinzi