Reputation: 13602
I have an IEnumerable object (IEnumerable<Class>
) and I would like to retrieve a specified line from the object. So if I'm on page two I would like to select row two from the IEnumerable object and then pass it on to another class etc.
I'm a bit stuck at the moment, any ideas?
Upvotes: 9
Views: 10836
Reputation: 417
An overload of the Take() method accepts a Range as the argument rather than a quantity, allowing you to specify the beginning and ending indices of the elements you want to retrieve. This eliminates the need for the compound Skip.Take approach shown in other answers.
For example:
.Take(0..2)
So you can do something like the following in order to page through an IEnumerable.
const int PageSize = 2000;
double totalPages = Math.Floor((double)myEnumerable.Count() / PageSize);
for (int currentPage = 0; currentPage <= totalPages; currentPage++)
{
var pageOfData = myEnumerable.Take((PageSize * currentPage)..((PageSize * currentPage) + PageSize));
// do work with current page of Data
}
Obviously there are a lot of different ways you can implement this, but it seems cleaner than the Skip.Take approach.
Upvotes: 0
Reputation: 48392
If I understand your requirements correctly, something like this paging mechanism should work:
int pageSize = 10;
int pageCount = 2;
iEnumerable.Skip(pageSize*pageCount).Take(pageSize);
This example shows 10 rows per page and a page number of 2. So, it will skip to page 2 and take the first row on that page.
Upvotes: 2
Reputation: 10653
Look at the functions .Take()
and .Skip()
. I normally do something like this:
IEnumerable<object> GetPage(IEnumerable<object> input, int page, int pagesize)
{
return input.Skip(page*pagesize).Take(pagesize);
}
Upvotes: 19
Reputation: 416
I've implemented a dynamic solution in vb.net, i hope helpful:
<Runtime.CompilerServices.Extension()>
Public Function Paginate(Of T As {Class})(source As T, skip As Integer, take As Integer) As T
If source IsNot Nothing AndAlso TypeOf source Is IEnumerable Then
Dim chunk = (From c In DirectCast(source, IEnumerable)).Skip(skip).Take(take).ToList
If chunk.Count = 0 Then Return Nothing
Return AutoMapper.Mapper.Map(chunk, GetType(T), GetType(T))
End If
Return source
End Function
Upvotes: 0
Reputation: 217233
Assuming that pages and rows start at 1, and there is a fixed number of rows per page (say 10), you need to transform the page number and the row to an index as follows:
Page 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 ... Row 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 ... ↓ Index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ...
Code:
int page = 2;
int row = 2;
int rowsPerPage = 10;
IEnumerable<MyClass> source = ...
MyClass result = source.ElementAt((page - 1) * rowsPerPage + (row - 1));
So to get row 2 on page 2, you need to skip the first page (10 elements) and then take the second element (index 1 in that page).
Upvotes: 1