#c# #math #pagination
#c# #математика #разбивка на страницы
Вопрос:
Я пытаюсь разобраться с этим, но ни за что на свете не могу!
Я вызываю разбитый на страницы API, каждая страница содержит 20 элементов. Я пытаюсь реализовать бесконечную прокрутку в своем пользовательском интерфейсе, чтобы использовать данные из этого API, и мы загружаем 12 элементов одновременно, поэтому мне нужно определить, с какого номера страницы мне нужно взять и сколько взять в этом API.
Например:
В настоящее время я нахожусь на пункте 10, и я хочу взять еще 20 элементов, это означает, что мне нужно взять 10 элементов со страницы 1, а затем 10 элементов со страницы 2. Но я не могу понять, как это сделать!
Это модель, с которой я работаю:
public class PagesToLoad
{
public int Page { get; set; }
public int Take { get; set; }
public int Skip { get; set; }
}
Вот сигнатура метода
public static List<PagesToLoad> GetPage(int currentlyLoaded, int toLoad, int maxItemsPerPage)
Я бы показал вам, что я пробовал, но это бессмысленно, поскольку я не могу понять, как это сделать.
Несколько примеров:
currentlyGoaded = 0, и я хочу загрузить 12, а значение maxItemsPerPage
равно 20. Итак, результаты должны быть:
new List<PagesToLoad>
{
new PagesToLoad
{
Page = 1,
Skip = 0,
Take = 12
},
}
currentlyLoaded = 10, и я хочу загрузить 20, а значение maxItemsPerPage
равно 20.
Итак, результаты должны быть:
new List<PagesToLoad>
{
new PagesToLoad
{
Page = 1,
Skip = 10,
Take = 10
},
new PagesToLoad
{
Page = 2,
Take = 10,
Skip = 0
}
}
Обновить:
Я написал несколько модульных тестов, чтобы попытаться протестировать некоторые из этих сценариев с использованием NUnit. Приведенные ниже тесты в настоящее время проверяют только то, что он возвращает правильную страницу, с которой мы должны брать, и в настоящее время не проверяет правильную позицию на текущей странице
[TestCaseSource(nameof(TestData))]
public void TestPaginationPagesToLoad(int currentlyLoaded, int toLoad, int maxItemsPerPage, int[] expectedPages)
{
var result = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, maxItemsPerPage);
var pages = result.Select(x => x.Page).ToArray();
Assert.That(pages.Length, Is.EqualTo(expectedPages.Length), "Did not contain the correct amount of pages");
for (int i = 0; i < pages.Length; i )
{
Assert.That(pages[i], Is.EqualTo(expectedPages[i]));
}
}
public static IEnumerable<TestCaseData> TestData
{
get
{
yield return new TestCaseData(0, 10, 20, new [] { 1 }).SetName("Load_First_Page");
yield return new TestCaseData(20, 10, 20, new [] { 2 }).SetName("Load_Second_Page");
yield return new TestCaseData(0, 20, 20, new [] { 1 }).SetName("Load_Full_First_Page");
yield return new TestCaseData(20, 20, 20, new [] { 2 }).SetName("Load_Full_Second_Page");
yield return new TestCaseData(10, 20, 20, new [] { 1, 2 }).SetName("Load_Half_First_Page_And_Half_Second_Page");
yield return new TestCaseData(19, 20, 20, new [] { 1, 2 }).SetName("Load_End_First_Page_And_Most_Second_Page");
}
}
Ответ №1:
Страница n содержит элементы (от sn — s 1) до sn включительно с обоих концов, где s — количество элементов на странице. Предположим, вы находитесь в пункте m и хотите взять еще k элементов. Затем вы хотите взять элементы m 1, m 2, …, m k. Первая страница, на которую вам нужно посмотреть, — это (m 1 — 1) / s 1, где деление — это целочисленное деление (только частное, без остатка). На этой странице вам нужно начать брать с (m 1 — 1) % s 1 и далее, где % — остаток после деления (по модулю). Последняя страница, на которую вам нужно будет посмотреть, — это (m k — 1) / s 1, и вам нужно будет посмотреть до (m k — 1) % s 1 .
Ваш пример:
s = 20
m = 10
k = 20
first page: (m 1 - 1) / s 1
= (10 1 - 1) / 20 1
= 10 / 20 1
= 0 1 = 1
start pos: (m 1 - 1) % s 1
= (10 1 - 1) % 20 1
= 10 % 20 1
= 10 1 = 11
last page: (m k - 1) / s 1
= (10 20 - 1) / 20 1
= 29/20 1
= 1 1 = 2
stop pos: (m k - 1) % s 1
= (10 20 - 1) % 20 1
= 29 % 20 1
= 9 1 = 10
Обратите внимание, что если last page > first page 1
вам нужно получить все промежуточные страницы.
РЕДАКТИРОВАТЬ: добавление некоторого C # может даже сработать!
List<PagesToLoad> GetPagesToload(int curItemIndex, int numItemsToGet, int itemsPerPage)
{
List<PagesToLoad> result = new List<pagesToLoad>();
int firstPage = curItemIndex / itemsPerPage 1;
int startPos = curItemIndex % itemsPerPage 1;
int lastItemIndex = curItemIndex numItemsToGet - 1;
int lastPage = lastItemIndex / itemsPerPage 1;
int stopPos = lastItemIndex % itemsPerPage 1;
PagesToLoad page1 = new PagesToLoad();
page1.Page = firstPage;
page1.Skip = curItemIndex;
page1.Take = numItemsToGet;
if (numItemsToGet startPos - 1 > itemsPerPage)
{
page1.Take = itemsPerPage - startPos 1;
result.Add(page1);
for (int i = firstPage 1; i < lastPage; i )
{
PagesToAdd nextPage = new PagesToAdd();
nextPage.Page = i;
nextPage.Skip = 0;
nextPage.Take = itemsPerPage;
result.Add(nextPage);
}
PagesToAdd pageN = new PagesToAdd();
pageN.Page = lastPage;
pageN.Skip = 0;
pageN.Take = stopPos;
result.Add(pageN);
}
else
{
result.Add(page1);
}
return resu<
}
Я не тестировал этот код и даже не пытался его скомпилировать, но это может дать вам представление о том, как все сделать правильно.
Комментарии:
1. @JamieRees Я постараюсь добавить немного C # 🙂
2. Большое спасибо за помощь, которая навела меня на правильный путь 🙂