4

If I have an array like this :

string[] mobile_numbers = plst.Where(r => !string.IsNullOrEmpty(r.Mobile))
                                          .Select(r => r.Mobile.ToString())
                                          .ToArray();

I want to paging this array and loop according to those pages .

Say the array count is 400 and i wanna to take the first 20 then the second 20 and so on until the end of array to process each 20 item .

How to do this with linq ? .

Soner Gönül
  • 94,086
  • 102
  • 195
  • 339
Anyname Donotcare
  • 10,649
  • 59
  • 212
  • 375

3 Answers3

18

Use Skip and Take methods for paging (but keep in mind that it will iterate collection for each page you are going to take):

int pageSize = 20;
int pageNumber = 2;
var result = mobile_numbers.Skip(pageNumber * pageSize).Take(pageSize);

If you need just split array on 'pages' then consider to use MoreLinq (available from NuGet) Batch method:

var pages = mobile_numbers.Batch(pageSize);

If you don't want to use whole library, then take a look on Batch method implementation. Or use this extension method:

public static IEnumerable<IEnumerable<T>> Batch<T>(
     this IEnumerable<T> source, int size)
{
    T[] bucket = null;
    var count = 0;

    foreach (var item in source)
    {
        if (bucket == null)            
            bucket = new T[size];


        bucket[count++] = item;

        if (count != size)            
            continue;            

        yield return bucket;

        bucket = null;
        count = 0;
    }

    if (bucket != null && count > 0)
        yield return bucket.Take(count).ToArray();
}

Usage:

int pageSize = 20;
foreach(var page in mobile_numbers.Batch(pageSize))
{   
    foreach(var item in page)
       // use items
}
Sergey Nudnov
  • 1,217
  • 7
  • 20
Sergey Berezovskiy
  • 224,436
  • 37
  • 411
  • 441
2

You need a batching operator.

There is one in MoreLinq that you can use.

You would use it like this (for your example):

foreach (var batch in mobile_numbers.Batch(20))
    process(batch);

batch in the above loop will be an IEnumerable of at most 20 items (the last batch may be smaller than 20; all the others will be 20 in length).

Matthew Watson
  • 96,889
  • 9
  • 144
  • 240
1

You can use .Skip(n).Take(x); to skip to the current index and take the amount required.

Take will only take the number available, i.e. what's left, when the number available is less than requested.

Grant Thomas
  • 43,307
  • 9
  • 83
  • 125