Skip to content

Linq Take() and Skip() are stated as Functinally complement, while it is not always true #5152

@dimmik

Description

@dimmik

Honestly, I am not sure if it is Documentation issue of code bug.
Documentation states:
The Take and Skip methods are functional complements. Given a sequence coll and an integer n, concatenating the results of coll.Take(n) and coll.Skip(n) yields the same sequence as coll.

The <xref:System.Linq.Enumerable.Take%2A> and <xref:System.Linq.Enumerable.Skip%2A> methods are functional complements. Given a sequence `coll` and an integer `n`, concatenating the results of `coll.Take(n)` and `coll.Skip(n)` yields the same sequence as `coll`.
(skip)
The <xref:System.Linq.Enumerable.Take%2A> and <xref:System.Linq.Enumerable.Skip%2A> methods are functional complements. Given a sequence `coll` and an integer `n`, concatenating the results of `coll.Take(n)` and `coll.Skip(n)` yields the same sequence as `coll`.
(take)

However, that is not always true, Take and Skip sometimes silently throw away elements, and taken.Concat(skipped) is not equal to original:

class TakeSkipEnumerableFail
    {
        private static readonly string[] array = Enumerable.Range(1, 7).Select(i => $"{i}").ToArray();
        private static int position = 0;
        private static IEnumerable<string> GetIEnumerable()
        {
            while (position < array.Length)
            {
                yield return array[position];
                position++;
            }
        }
        static void Main()
        {
            var sequence = GetIEnumerable();
            var before = sequence.Take(3);
            var after = sequence.Skip(3);
            var concat = before.Concat(after); // should be 1,2,3,4,5,6,7
            var result = $"concat: {string.Join(",", concat)}"; // but actually it is 1,2,3,6,7
            Console.WriteLine(result);
        }
    }

Most probably it is due to nature of this very IEnumerable (it is true for enumerations that are not repeatable), but it makes sense to mention this in documentation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Pri3Indicates issues/PRs that are low priorityarea-System.Linqhelp wantedGood for community contributors to help [up-for-grabs]

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions