<p>How do you page through a collection in LINQ given that you have a <code>startIndex</code> and a <code>count</code>?</p>

[{'answer_id': 68, 'author': 'Nick Berardi', 'author_id': 17, 'author_profile': 'https://Stackoverflow.com/users/17', 'pm_score': 6, 'selected': False, 'text': '<p>It is very simple with the <code>Skip</code> and <code>Take</code> extension methods.</p>\n\n<pre><code>var query = from i in ideas\n            select i;\n\nvar paggedCollection = query.Skip(startIndex).Take(count);\n</code></pre>\n'}, {'answer_id': 4521, 'author': 'Mike Minutillo', 'author_id': 358, 'author_profile': 'https://Stackoverflow.com/users/358', 'pm_score': 7, 'selected': True, 'text': '<p>A few months back I wrote a blog post about  Fluent Interfaces and LINQ which used an Extension Method on <code>IQueryable&lt;T&gt;</code> and another class to provide the following natural way of paginating a LINQ collection.</p>\n\n<pre><code>var query = from i in ideas\n            select i;\nvar pagedCollection = query.InPagesOf(10);\nvar pageOfIdeas = pagedCollection.Page(2);\n</code></pre>\n\n<p>You can get the code from the MSDN Code Gallery Page: <a href="http://code.msdn.microsoft.com/productschallenge" rel="noreferrer">Pipelines, Filters, Fluent API and LINQ to SQL</a>.</p>\n'}, {'answer_id': 6719914, 'author': 'Nico', 'author_id': 452101, 'author_profile': 'https://Stackoverflow.com/users/452101', 'pm_score': 4, 'selected': False, 'text': '<p>This question is somewhat old, but I wanted to post my paging algorithm that shows the whole procedure (including user interaction).</p>\n\n<pre><code>const int pageSize = 10;\nconst int count = 100;\nconst int startIndex = 20;\n\nint took = 0;\nbool getNextPage;\nvar page = ideas.Skip(startIndex);\n\ndo\n{\n    Console.WriteLine("Page {0}:", (took / pageSize) + 1);\n    foreach (var idea in page.Take(pageSize))\n    {\n        Console.WriteLine(idea);\n    }\n\n    took += pageSize;\n    if (took &lt; count)\n    {\n        Console.WriteLine("Next page (y/n)?");\n        char answer = Console.ReadLine().FirstOrDefault();\n        getNextPage = default(char) != answer &amp;&amp; \'y\' == char.ToLowerInvariant(answer);\n\n        if (getNextPage)\n        {\n            page = page.Skip(pageSize);\n        }\n    }\n}\nwhile (getNextPage &amp;&amp; took &lt; count);\n</code></pre>\n\n<p>However, if you are after performance, and in production code, we\'re all after performance, you shouldn\'t use LINQ\'s paging as shown above, but rather the underlying <code>IEnumerator</code> to implement paging yourself. As a matter of fact, it is as simple as the LINQ-algorithm shown above, but more performant:</p>\n\n<pre><code>const int pageSize = 10;\nconst int count = 100;\nconst int startIndex = 20;\n\nint took = 0;\nbool getNextPage = true;\nusing (var page = ideas.Skip(startIndex).GetEnumerator())\n{\n    do \n    {\n        Console.WriteLine("Page {0}:", (took / pageSize) + 1);\n\n        int currentPageItemNo = 0;\n        while (currentPageItemNo++ &lt; pageSize &amp;&amp; page.MoveNext())\n        {\n            var idea = page.Current;\n            Console.WriteLine(idea);\n        }\n\n        took += pageSize;\n        if (took &lt; count)\n        {\n            Console.WriteLine("Next page (y/n)?");\n            char answer = Console.ReadLine().FirstOrDefault();\n            getNextPage = default(char) != answer &amp;&amp; \'y\' == char.ToLowerInvariant(answer);\n        }\n    }\n    while (getNextPage &amp;&amp; took &lt; count);\n}\n</code></pre>\n\n<p>Explanation: The downside of using <code>Skip()</code> for multiple times in a "cascading manner" is, that it will not really store the "pointer" of the iteration, where it was last skipped. - Instead the original sequence will be front-loaded with skip calls, which will lead to "consuming" the already "consumed" pages over and over again. - You can prove that yourself, when you create the sequence <code>ideas</code> so that it yields side effects. -> Even if you have skipped 10-20 and 20-30 and want to process 40+, you\'ll see all side effects of 10-30 being executed again, before you start iterating 40+.\nThe variant using <code>IEnumerable</code>\'s interface directly, will instead remember the position of the end of the last logical page, so no explicit skipping is needed and side effects won\'t be repeated.</p>\n'}, {'answer_id': 9787122, 'author': 'Spoike', 'author_id': 3713, 'author_profile': 'https://Stackoverflow.com/users/3713', 'pm_score': 4, 'selected': False, 'text': '<p>I solved this a bit differently than what the others have as I had to make my own paginator, with a repeater. So I first made a collection of page numbers for the collection of items that I have:</p>\n\n<pre><code>// assumes that the item collection is "myItems"\n\nint pageCount = (myItems.Count + PageSize - 1) / PageSize;\n\nIEnumerable&lt;int&gt; pageRange = Enumerable.Range(1, pageCount);\n   // pageRange contains [1, 2, ... , pageCount]\n</code></pre>\n\n<p>Using this I could easily partition the item collection into a collection of "pages". A page in this case is just a collection of items (<code>IEnumerable&lt;Item&gt;</code>). This is how you can do it using <code>Skip</code> and <code>Take</code> together with selecting the index from the <code>pageRange</code> created above:</p>\n\n<pre><code>IEnumerable&lt;IEnumerable&lt;Item&gt;&gt; pageRange\n    .Select((page, index) =&gt; \n        myItems\n            .Skip(index*PageSize)\n            .Take(PageSize));\n</code></pre>\n\n<p>Of course you have to handle each page as an additional collection but e.g. if you\'re nesting repeaters then this is actually easy to handle.</p>\n\n<hr>\n\n<p>The <em>one-liner TLDR</em> version would be this:</p>\n\n<pre><code>var pages = Enumerable\n    .Range(0, pageCount)\n    .Select((index) =&gt; myItems.Skip(index*PageSize).Take(PageSize));\n</code></pre>\n\n<p>Which can be used as this:</p>\n\n<pre><code>for (Enumerable&lt;Item&gt; page : pages) \n{\n    // handle page\n\n    for (Item item : page) \n    {\n        // handle item in page\n    }\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/66', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/17/']