Определение количества предметов в разбивке на страницы - PullRequest
2 голосов
/ 16 апреля 2019

Я пытаюсь решить это, но на всю жизнь не могу!

Я звоню по 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)

Я бы показалто, что я пробовал, но это бессмысленно, так как я не могу понять, как это сделать.

Несколько примеров:

nowLoaded = 0, и я хочу загрузить 12 и maxItemsPerPage равно 20. Таким образом, результаты должны быть:

new List<PagesToLoad>
{
    new PagesToLoad
    {
        Page = 1,
        Skip = 0,
        Take = 12
    },
}

currentLoaded = 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 Ответ

2 голосов
/ 16 апреля 2019

Страница 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 result;
}

Я не тестировал этот код и даже не пытался его скомпилировать - но это может дать вам достаточно идеи, чтобы получить егоправый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...