Các mã mà bạn trình bày sẽ chỉ lặp các mục trong danh sách một lần, như những người khác đã chỉ ra.
Tuy nhiên, chỉ cung cấp cho bạn các mục cho một trang. Nếu bạn đang xử lý nhiều trang, bạn phải gọi mã đó một lần cho mỗi trang (vì một nơi nào đó bạn phải tăng thêm currentPage
, phải không?).
Những gì tôi có nghĩa là bạn phải làm gì đó như thế này:
for (int currentPage = 0; currentPage < numPages; ++currentPage)
{
foreach (var item in items.Skip(currentPage*itemsPerPage).Take(itemsPerPage))
{
//Do stuff
}
}
Bây giờ nếu bạn làm rằng, sau đó bạn sẽ được lặp lại trình tự nhiều lần - một lần cho mỗi trang. Lần lặp đầu tiên sẽ chỉ đi xa đến cuối trang đầu tiên, nhưng lần tiếp theo sẽ lặp lại từ đầu đến cuối trang thứ hai (thông qua Skip()
và Take()
) - và bước tiếp theo sẽ lặp lại từ đầu đến cuối trang thứ ba. Và cứ thế.
Để tránh điều đó, bạn có thể viết một phương pháp mở rộng cho IEnumerable<T>
để phân chia dữ liệu thành các lô (bạn cũng có thể mô tả là "phân trang" dữ liệu thành "trang").
Thay vì chỉ trình bày một IEnumerable của IEnumerables, nó có thể hữu ích hơn để quấn từng lô trong một lớp học để cung cấp các chỉ số hàng loạt cùng với các mục trong hàng loạt, như vậy:
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());
}
}
Phần mở rộng này phương pháp không đệm dữ liệu, và nó chỉ lặp qua nó một lần.
Với phương pháp mở rộng này, nó trở nên dễ đọc hơn để sắp xếp các mục. Lưu ý rằng ví dụ này liệt kê qua TẤT CẢ các mục cho tất cả các trang, không giống như ví dụ của OP mà chỉ lặp qua các mục cho một trang:
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();
}
Đặt điểm ngắt và xem. –
Đó chỉ là một phần. Bạn đang gọi đó từ một vòng lặp quá? –