tags:

views:

83

answers:

5

I have a List<User> collection, and want to do in-memory paging using a start and end index.

What's the best way to do this?

A: 

Assuming you are using .NET 3.5+, you can use linq to do this: http://solidcoding.blogspot.com/2007/11/paging-with-linq.html

markt
+4  A: 
list.Skip(pageIndex * pageSize).Take(pageSize);

Assumes a 0-based pageIndex. Or if you truly have an end index:

list.Skip(startIndex).Take(endIndex - startIndex);
Kirk Woll
this will suck in performance.
Aliostad
I prefer readability to knee-jerk over-optimization myself. But I agree it depends on the given situation.
Kirk Woll
will this break if you past the end of the collection?
Blankman
@Blankman, no, neither Skip nor Take will throw an exception if you reach the end of the enumerable. i.e. `new int[0].Skip(5).Take(10);` will run just fine.
Kirk Woll
+1  A: 

Is this code example enough? Your question isn't very detailed, but this is essentially how you'd do it.

// fill this in
int pageSize = 10;

// This figures out the total number of pages for you. The modulo stuff
// takes care of the case when the last page has less than pageSize items.
// It's the same as Math.Ceiling() but using integers.
int numberOfPages = (aList.Count / pageSize)
    + (aList.Count % pageSize == 0 ? 0 : 1);

// 0 based
int currentPage = 0;

IEnumerable<SomeType> itemsOnThisPage = aList.Skip(currentPage * pageSize).Take(pageSize);
Matti Virkkunen
i need to return List<> not IENumerable, thanks though!
Blankman
Blankman: There's a `ToList` method that converts it to a `List<T>`. It's worth thinking about whether you really need a list or not, though. Sometimes enumerables are more appropriate.
Matti Virkkunen
+1  A: 

Using Linq is convenient but not performant. I will go with the classic:

  const int ItemPerPage = 20;
  int pageNo = 5;
  for (int i = pageNo * ItemPerPage; i < (pageNo * (ItemPerPage + 1)); i++)
  {
     Console.WriteLine(items[i]);
  }
Aliostad
A: 

This might meet your needs. Ive tried to make it use start and end index as requested. Call like GetPages(myusers, 10); for 10 items pre page.

 public IEnumerable<IEnumerable<T>> GetPages<T>(
         IList<T> source, int pageLength)
    {
        //validation here

        for (int startIndex = 0; 
             startIndex < source.Count;
             startIndex += pageLength)
        {
            yield return Page(source, startIndex, pageLength);
        }
    }

    public  IEnumerable<T> GetPage<T>(
         IList<T> source, int startIndex, int length)
    {
        //validation here

        for (int i = startIndex; 
             i < startIndex + length && i < source.Count; 
             i++)
        {
            yield return source[i];
        }
    }

Then do

 List<IEnumerable<User>> pages = GetPages(myusers, 10).ToList();

now you can index the pages (0 based)

Bear Monkey