Il codice che si presenti saranno iterare solo gli elementi della lista una volta, come altri hanno fatto notare.
Tuttavia, questo fornisce solo gli elementi per una pagina. Se gestisci più pagine, devi chiamare quel codice una volta per ogni pagina (perché da qualche parte devi incrementare il numero currentPage
, giusto?).
Quello che voglio dire è che si deve fare qualcosa di simile:
for (int currentPage = 0; currentPage < numPages; ++currentPage)
{
foreach (var item in items.Skip(currentPage*itemsPerPage).Take(itemsPerPage))
{
//Do stuff
}
}
Ora, se lo fai che, allora si avrà essere iterazione i tempi multipli di sequenza - una volta per ogni pagina. La prima iterazione andrà solo fino alla fine della prima pagina, ma la prossima verrà ripetuta dall'inizio alla fine della seconda pagina (tramite lo Skip()
e lo Take()
) - e la prossima verrà iterata dall'inizio alla fine fine della terza pagina. E così via.
Per evitare che sia possibile scrivere un metodo di estensione per IEnumerable<T>
che partiziona i dati in batch (che è anche possibile descrivere come "impaginando" i dati in "pagine").
Piuttosto che presentando un'IEnumerable di IEnumerables, può essere più utile per avvolgere ogni lotto in una classe di fornire l'indice lotto insieme ai componenti di una partita, in questo modo:
public sealed class Batch<T>
{
public readonly int Index;
public readonly IEnumerable<T> Items;
public Batch(int index, IEnumerable<T> items)
{
Index = index;
Items = items;
}
}
public static class EnumerableExt
{
// Note: Not threadsafe, so not suitable for use with Parallel.Foreach() or IEnumerable.AsParallel()
public static IEnumerable<Batch<T>> Partition<T>(this IEnumerable<T> input, int batchSize)
{
var enumerator = input.GetEnumerator();
int index = 0;
while (enumerator.MoveNext())
yield return new Batch<T>(index++, nextBatch(enumerator, batchSize));
}
private static IEnumerable<T> nextBatch<T>(IEnumerator<T> enumerator, int blockSize)
{
do { yield return enumerator.Current; }
while (--blockSize > 0 && enumerator.MoveNext());
}
}
Questa estensione il metodo non memorizza i dati nel buffer e lo esegue solo una volta.
Dato questo metodo di estensione, diventa più leggibile raggruppare gli articoli. Si noti che questo esempio enumera attraverso TUTTI gli articoli per tutte le pagine, a differenza dell'esempio dell'OP che scorre solo attraverso gli elementi per una pagina:
var items = Enumerable.Range(10, 50); // Pretend we have 50 items.
int itemsPerPage = 20;
foreach (var page in items.Partition(itemsPerPage))
{
Console.Write("Page " + page.Index + " items: ");
foreach (var i in page.Items)
Console.Write(i + " ");
Console.WriteLine();
}
Inserire un punto di interruzione e vedere. –
Questo è solo uno split. Lo stai chiamando anche tu da un ciclo? –