How to take all but the last element in a sequence using LINQ?

c# split take all but last
skip last element in list c#
c# get all but last item in array
linq take n at a time
skip and take in linq query
c# all elements except last
c# get all except last
c# join array except last element

Let's say I have a sequence.

IEnumerable<int> sequence = GetSequenceFromExpensiveSource();
// sequence now contains: 0,1,2,3,...,999999,1000000

Getting the sequence is not cheap and is dynamically generated, and I want to iterate through it once only.

I want to get 0 - 999999 (i.e. everything but the last element)

I recognize that I could do something like:

sequence.Take(sequence.Count() - 1);

but that results in two enumerations over the big sequence.

Is there a LINQ construct that lets me do:

sequence.TakeAllButTheLastElement();

I don't know a Linq solution - But you can easily code the algorithm by yourself using generators (yield return).

public static IEnumerable<T> TakeAllButLast<T>(this IEnumerable<T> source) {
    var it = source.GetEnumerator();
    bool hasRemainingItems = false;
    bool isFirst = true;
    T item = default(T);

    do {
        hasRemainingItems = it.MoveNext();
        if (hasRemainingItems) {
            if (!isFirst) yield return item;
            item = it.Current;
            isFirst = false;
        }
    } while (hasRemainingItems);
}

static void Main(string[] args) {
    var Seq = Enumerable.Range(1, 10);

    Console.WriteLine(string.Join(", ", Seq.Select(x => x.ToString()).ToArray()));
    Console.WriteLine(string.Join(", ", Seq.TakeAllButLast().Select(x => x.ToString()).ToArray()));
}

Or as a generalized solution discarding the last n items (using a queue like suggested in the comments):

public static IEnumerable<T> SkipLastN<T>(this IEnumerable<T> source, int n) {
    var  it = source.GetEnumerator();
    bool hasRemainingItems = false;
    var  cache = new Queue<T>(n + 1);

    do {
        if (hasRemainingItems = it.MoveNext()) {
            cache.Enqueue(it.Current);
            if (cache.Count > n)
                yield return cache.Dequeue();
        }
    } while (hasRemainingItems);
}

static void Main(string[] args) {
    var Seq = Enumerable.Range(1, 4);

    Console.WriteLine(string.Join(", ", Seq.Select(x => x.ToString()).ToArray()));
    Console.WriteLine(string.Join(", ", Seq.SkipLastN(3).Select(x => x.ToString()).ToArray()));
}

how to take all array elements except last element in C#, var remStrings = queries.Take(queries.Length - 1);. No need to Reverse and Skip . Just take one less element than there are in the array. If you just want to get the very last element from this sequence with no query then you can use the Last operator: Singer singer = singers.Last (); Console.WriteLine (singer.LastName); This will select David Bowie from the list. You can also send an item selector to get the last element which matches the query:

As an alternative to creating your own method and in a case the elements order is not important, the next will work:

var result = sequence.Reverse().Skip(1);

How to skip last 2 records and get all other records with linq?, With Take and Skip you can get any range you want. Bypasses a specified number of elements in a sequence and then returns the remaining� I want to get 0 – 999999 (i.e. everything but the last element) I recognize that I could do something like: sequence.Take(sequence.Count() - 1); but that results in two enumerations over the big sequence. Is there a LINQ construct that lets me do: sequence.TakeAllButTheLastElement();

Because I'm not a fan of explicitly using an Enumerator, here's an alternative. Note that the wrapper methods are needed to let invalid arguments throw early, rather than deferring the checks until the sequence is actually enumerated.

public static IEnumerable<T> DropLast<T>(this IEnumerable<T> source)
{
    if (source == null)
        throw new ArgumentNullException("source");

    return InternalDropLast(source);
}

private static IEnumerable<T> InternalDropLast<T>(IEnumerable<T> source)
{
    T buffer = default(T);
    bool buffered = false;

    foreach (T x in source)
    {
        if (buffered)
            yield return buffer;

        buffer = x;
        buffered = true;
    }
}

As per Eric Lippert's suggestion, it easily generalizes to n items:

public static IEnumerable<T> DropLast<T>(this IEnumerable<T> source, int n)
{
    if (source == null)
        throw new ArgumentNullException("source");

    if (n < 0)
        throw new ArgumentOutOfRangeException("n", 
            "Argument n should be non-negative.");

    return InternalDropLast(source, n);
}

private static IEnumerable<T> InternalDropLast<T>(IEnumerable<T> source, int n)
{
    Queue<T> buffer = new Queue<T>(n + 1);

    foreach (T x in source)
    {
        buffer.Enqueue(x);

        if (buffer.Count == n + 1)
            yield return buffer.Dequeue();
    }
}

Where I now buffer before yielding instead of after yielding, so that the n == 0 case does not need special handling.

Enumerable.Last Method (System.Linq), Returns the last element of a sequence. example demonstrates how to use Last<TSource>(IEnumerable<TSource>) to return the last element of an array. C# In LINQ, the Last () method is useful to return the last element from the list/collection and this LINQ Last () method will throw an exception in case if the list/collection returns no elements. Syntax of LINQ Last () Method Following is the syntax of using LINQ Last () method to get the last element from the list using LINQ Last () method.

The Enumerable.SkipLast(IEnumerable<TSource>, Int32) method was added in .NET Standard 2.1. It does exactly what you want.

IEnumerable<int> sequence = GetSequenceFromExpensiveSource();

var allExceptLast = sequence.SkipLast(1);

From https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.skiplast

Returns a new enumerable collection that contains the elements from source with the last count elements of the source collection omitted.

LINQ | Element Operator, Or return the last element which specifies the given condition. This method use of Last operator. using System;. using System.Linq;. using System.Collections. ' Create an array of integers. Dim numbers() As Integer = {9, 34, 65, 92, 87, 435, 3, 54, 83, 23, 87, 67, 12, 19} ' Get the last element in the array whose value is ' greater than 80. Dim last As Integer = numbers.Last(Function(num) num > 80) ' Display the result. Console.WriteLine(last) ' This code produces the following output: ' ' 87 Remarks

Nothing in the BCL (or MoreLinq I believe), but you could create your own extension method.

public static IEnumerable<T> TakeAllButLast<T>(this IEnumerable<T> source)
{
    using (var enumerator = source.GetEnumerator())
        bool first = true;
        T prev;
        while(enumerator.MoveNext())
        {
            if (!first)
                yield return prev;
            first = false;
            prev = enumerator.Current;
        }
    }
}

Skip and Take - Using C# LINQ - A Practical Overview, The difference is subtle, and can often be ignored, but there are some Where the Take() method, returns a sequence containing the first n elements of the� var result = (from t in MyDC where t.UserID == 6 orderby t.UpdateTime select t.ID).Last(); Basically, I'm using Linq-to-Sql and it doesn't support the .Last operator. I could retrieve all the records of the user and then using linq to objects to get my value but I'm wondering how to do this with linq-to-sql and return only one record.

LINQ: Introducing The Skip Last Operators, Returns all but a specified number of contiguous elements from the end of a sequence. Hide Shrink Copy Code. int[] grades = { 59, 82, 70, 56,� 2. Enumerable.Take Method. System.Linq.Enumerable.Take method returns a specified number of contiguous elements from the start of a sequence. The following code example demonstrates how to use Take to return all elements from the array except the last one.

Remove last element from an array in C#, We can use any of the following methods to easily remove the last element from an array: how to use Take to return all elements from the array except the last one. Linq namespace filters a sequence of values based on a predicate. i would like to iterate over the items of a List<T>, except the first, preserving the order.Is there an elegant way to do it with LINQ using a statement like: foreach (var item in list.Skip(1).

LINQ Last() Method, Following is the syntax of using LINQ Last() method to get the last element from the list using LINQ Last() method. C# Code. int result = objList.Last();. VB. In LINQ, you can count the total number of elements present in the given sequence by using the Count Method. This method returns the total number of elements present in the given sequence. This method can be overloaded in two different ways: Count<TSource> (): This method returns the total number of elements present in the given specified sequence. The return type of this method is System.Int32.

Comments
  • You've to choose between an O(2n) time or O(count) space efficiency algorithm, where the latter also needs to move items in an internal array.
  • Dario, would you please explain for someone who's not that into big o-notation?
  • See also this duplicate question: stackoverflow.com/q/4166493/240733
  • I ended up with caching it by converting collection to List and then calling sequenceList.RemoveAt(sequence.Count - 1);. In my case it is acceptable because after all LINQ manipulations I have to convert it to array or IReadOnlyCollection anyway. I wonder what is your use case where you do not even consider caching? As I can see even approved answer does some caching so simple converting to List is much easier and shorter in my opinion.
  • Now can you generalize it to take all but the final n?
  • Nice. One small error; queue size should be initialized to n + 1 since that is the max size of the queue.
  • ReSharper doesn't understand your code (assignment in conditional expression) but i kinda like it +1
  • Note that this requires that you have enough memory to store the entire sequence, and of course it STILL iterates the entire sequence twice, once to build the reversed sequence and once to iterate it. Pretty much this is worse than the Count solution no matter how you slice it; it's slower AND takes far more memory.
  • I don't know how the 'Reverse' method work, so I'm not sure about amount of memory it use. But I agree about two iterations. This method shouldn't be used on large collections or if a performance is important.
  • Well, how would you implement Reverse? Can you figure out a way in general to do it without storing the entire sequence?
  • I like it, and it does meet the criteria of not generating the sequence twice.