5

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
  • 97,193
  • 102
  • 206
  • 364
Anyname Donotcare
  • 11,113
  • 66
  • 219
  • 392

3 Answers3

20

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,327
  • 11
  • 20
Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459
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
  • 104,400
  • 10
  • 158
  • 276
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
  • 44,454
  • 10
  • 85
  • 129