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

前端 未结 22 1394
南笙
南笙 2020-11-30 02:51

Let\'s say I have a sequence.

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


        
相关标签:
22条回答
  • 2020-11-30 03:21

    A simple way would be to just convert to a queue and dequeue until only the number of items you want to skip is left.

    public static IEnumerable<T> SkipLast<T>(this IEnumerable<T> source, int n)
    {
        var queue = new Queue<T>(source);
    
        while (queue.Count() > n)
        {
            yield return queue.Dequeue();
        }
    }
    
    0 讨论(0)
  • 2020-11-30 03:22

    if you don't have time to roll out your own extension, here's a quicker way:

    var next = sequence.First();
    sequence.Skip(1)
        .Select(s => 
        { 
            var selected = next;
            next = s;
            return selected;
        });
    
    0 讨论(0)
  • 2020-11-30 03:24

    A slight variation on the accepted answer, which (for my tastes) is a bit simpler:

        public static IEnumerable<T> AllButLast<T>(this IEnumerable<T> enumerable, int n = 1)
        {
            // for efficiency, handle degenerate n == 0 case separately 
            if (n == 0)
            {
                foreach (var item in enumerable)
                    yield return item;
                yield break;
            }
    
            var queue = new Queue<T>(n);
            foreach (var item in enumerable)
            {
                if (queue.Count == n)
                    yield return queue.Dequeue();
    
                queue.Enqueue(item);
            }
        }
    
    0 讨论(0)
  • 2020-11-30 03:25

    Could be:

    var allBuLast = sequence.TakeWhile(e => e != sequence.Last());
    

    I guess it should be like de "Where" but preserving the order(?).

    0 讨论(0)
  • 2020-11-30 03:26
        public static IEnumerable<T> NoLast<T> (this IEnumerable<T> items) {
            if (items != null) {
                var e = items.GetEnumerator();
                if (e.MoveNext ()) {
                    T head = e.Current;
                    while (e.MoveNext ()) {
                        yield return head; ;
                        head = e.Current;
                    }
                }
            }
        }
    
    0 讨论(0)
  • 2020-11-30 03:27

    I would probably do something like this:

    sequence.Where(x => x != sequence.LastOrDefault())
    

    This is one iteration with a check that it isn't the last one for each time though.

    0 讨论(0)
提交回复
热议问题