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

前端 未结 22 1397
南笙
南笙 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:12

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

    public static IEnumerable TakeAllButLast(this IEnumerable 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 SkipLastN(this IEnumerable source, int n) {
        var  it = source.GetEnumerator();
        bool hasRemainingItems = false;
        var  cache = new Queue(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()));
    }
    

提交回复
热议问题