Подтвердить что ты не робот

Алгоритм/псевдокод для создания пейджинговых ссылок?

Может ли кто-нибудь предоставить код или псевдокод для создания пейджинговых ссылок в StackOverflow?

Я продолжаю ломать голову, но не могу придумать достойный способ построить динамические ссылки, которые всегда показывают 2 страницы вокруг текущего, плюс первый и последний.

Пример: 1 ... 5 6 7 ... 593

4b9b3361

Ответ 1

Уже есть несколько других ответов, но я хотел бы показать вам подход, который я принял для его решения: Во-первых, давайте посмотрим, как Qaru обрабатывает обычные случаи и крайние случаи. Каждая из моих страниц отображает 10 результатов, поэтому, чтобы узнать, что она делает для 1 страницы, найдите тег, который имеет менее 11 записей: usability работает сегодня. Мы видим, что ничего не отображается, что имеет смысл.

Как насчет 2 страниц? Найдите тег, который содержит от 11 до 20 записей (emacs работает сегодня). Мы видим: " 1 2 Next" или "Prev 1 2", в зависимости от того, на какой странице мы находимся.

3 страницы? " 1 2 3... 3 Next", "Prev 1 2 3 Next" и "Prev 1... 2 3", Интересно, что мы можем видеть, что Qaru сам не очень хорошо обрабатывает этот крайний регистр: он должен отображать " 1 2... 3 Далее"

4 страницы? " 1 2 3... 4 Next", "Prev 1 2 3... 4 Next", "Prev 1... 2 3 4 Next" и "Prev 1... 3 4"

Наконец, посмотрим на общий случай, N страниц: " 1 2 3... N Далее", "Предыдущая 1 2 3... N Далее", "Предыдущая 1... 2 3 4... N Далее", "Предыдущая 1... 3 4 5... N Далее" и т.д.

Позвольте обобщить, основываясь на том, что мы видели: Кажется, что этот алгоритм имеет общие черты:

  • Если мы не на первой странице, отобразите ссылку на Prev
  • Всегда показывать номер первой страницы
  • Всегда показывать текущий номер страницы
  • Всегда показывать страницу до этой страницы и страницу после этой страницы.
  • Всегда показывать номер последней страницы
  • Если мы не на последней странице, отобразите ссылку на Next

Пусть игнорирует регистр края одной страницы и делает первую попытку алгоритма: (Как уже упоминалось, код для фактической печати ссылок будет более сложным. Представьте себе, что каждое место мы размещаем номер страницы, Prev или Next как вызов функции, который вернет правильный URL.)

function printPageLinksFirstTry(num totalPages, num currentPage)
  if ( currentPage > 1 )
    print "Prev"
  print "1"
  print "..."
  print currentPage - 1
  print currentPage
  print currentPage + 1
  print "..."
  print totalPages
  if ( currentPage < totalPages )
    print "Next"
endFunction

Эта функция работает нормально, но она не учитывает, находимся ли мы на первой или последней странице. Рассматривая приведенные выше примеры, мы хотим отобразить..., если текущая страница находится на расстоянии два или более.

function printPageLinksHandleCloseToEnds(num totalPages, num currentPage)
  if ( currentPage > 1 )
    print "Prev"
  print "1"
  if ( currentPage > 2 )
    print "..."
  if ( currentPage > 2 )
    print currentPage - 1
  print currentPage
  if ( currentPage < totalPages - 1 )
    print currentPage + 1
  if ( currentPage < totalPages - 1 )
    print "..."
  print totalPages
  if ( currentPage < totalPages )
    print "Next"
endFunction

Как вы можете видеть, у нас есть некоторое дублирование. Мы можем продолжить и очистить его для чтения:

function printPageLinksCleanedUp(num totalPages, num currentPage)
  if ( currentPage > 1 )
    print "Prev"
  print "1"
  if ( currentPage > 2 )
    print "..."
    print currentPage - 1
  print currentPage
  if ( currentPage < totalPages - 1 )
    print currentPage + 1
    print "..."
  print totalPages
  if ( currentPage < totalPages )
    print "Next"
endFunction

Осталось только две проблемы. Во-первых, мы не печатаем правильно для одной страницы, а во-вторых, мы будем печатать "1" дважды, если мы находимся на первой или последней странице. Пусть очистят их обоих за один раз:

function printPageLinksFinal(num totalPages, num currentPage)
  if ( totalPages == 1 )
    return

  if ( currentPage > 1 )
    print "Prev"

  print "1"

  if ( currentPage > 2 )
    print "..."
    print currentPage - 1

  if ( currentPage != 1 and currentPage != totalPages )
    print currentPage

  if ( currentPage < totalPages - 1 )
    print currentPage + 1
    print "..."

  print totalPages

  if ( currentPage < totalPages )
    print "Next"

endFunction

Собственно, я соврал: у нас есть одна оставшаяся проблема. Если у вас есть как минимум 4 страницы и находятся на первой или последней странице, вы получаете дополнительную страницу на дисплее. Вместо " 1 2... 10 Далее" вы получаете " 1 2 3... 10 Далее". Чтобы точно соответствовать тому, что происходит в Stack Overflow, вам нужно будет проверить эту ситуацию:

function printPageLinksFinalReally(num totalPages, num currentPage)
  if ( totalPages == 1 )
    return

  if ( currentPage > 1 )
    print "Prev"

  print "1"

  if ( currentPage > 2 )
    print "..."
    if ( currentPage == totalPages and totalPages > 3 )
      print currentPage - 2
    print currentPage - 1

  if ( currentPage != 1 and currentPage != totalPages )
    print currentPage

  if ( currentPage < totalPages - 1 )
    print currentPage + 1
    if ( currentPage == 1 and totalPages > 3 )
      print currentPage + 2
    print "..."

  print totalPages

  if ( currentPage < totalPages )
    print "Next"

endFunction

Надеюсь, это поможет!

Ответ 2

Элементы управления обычно показывают элементы управления для: P1, Pn, Pc (текущая страница), Pc + 1, Pc-1. Единственный раз, когда это изменяется, на обоих концах диапазона поискового вызова {Pc < P3 или Pc > (Pn-3)}

  • Первым шагом является, очевидно, определение количества страниц:

numPages = ceiling(totalRecords / numPerPage)

  • Если у вас есть 4 или меньше, выпадаете в этот момент, потому что по приведенным выше правилам поисковый вызов всегда будет исправлен (P1, P2, Pn-1, Pn), где каждый будет иметь Pc

  • else, у вас есть три "состояния"

а. (Pc < P3) - показать P1, P2, P3, Pn, Далее, если Pc > 1, показать ссылку "prev" до P1.

б. (Pc > Pn-2), поэтому покажите Prev, P1, Pn-2, Pn-1, Pn, покажите ссылку Next, если Pc < Рп

с. Show Prev, P1, Pc -1, Pc, Pc +1, Pn, Next

Легко, как пирог в псевдокоде. Петли могут быть немного неприятными, когда они реализованы, поскольку вам нужно выполнить некоторые итерации, чтобы создать ссылки.

Изменить: Конечно, Prev и Next идентичны Pc +/- 1

Ответ 3

Хорошо, если вы знаете текущую страницу, довольно просто, просто вычтите число на 1 и добавьте ее на 1, затем проверьте эти числа на границах и всегда показывайте первую и последнюю страницу, а затем, t в последовательности, добавьте эллипсы.

Или вы спрашиваете о получении общего количества страниц и определении текущего номера страницы...?

Ответ 4

public void PageLinks(int currentPage, int lastPage) {
    if (currentPage > 2) 
        Add('[1]', '...');
    for(int i=Math.Max(1, currentPage-1); i< Math.Min(currentPage+1, lastPage); i++)
        Add('[i]');
    if (currentPage < lastPage-1)
        Add('...', '[lastpage]');
}

lastPage вычисляется как Math.Ceiling(totalRecords/RecordsPerPage).

Ммм. фактически, в случае, если текущая страница равна 3, она все еще показывает [1]... [2] [3] [4]... [xxx] Я думаю, что эллипсы в этом случае лишние. Но как это работает.

Изменить: форматы предварительного просмотра правильно закодированы, почему он искалечен? конечно, его просто псевдокод.... но все же....

Ответ 5

Это мой подход к созданию пейджинговой ссылки. Следующий код Java - это просто псевдо.

package com.edde;

/**
 * @author Yang Shuai
 */
public class Pager {

    /**
     * This is a method used to display the paging links(pagination or sometimes called pager).
     * The totalPages are the total page you need to display. You can get this value using the
     * formula:
     * 
     *     total_pages = total_records / items_per_page
     * 
     * This methods is just a pseudo-code.
     * 
     * 
     * @param totalPages how many pages you need to display
     * @param currentPage you are in which page now
     */
    public static void printPageLinks(int totalPages, int currentPage) {

        // how many pages to display before and after the current page
        int x = 2;

        // if we just have one page, show nothing
        if (totalPages == 1) {
            return;
        }

        // if we are not at the first page, show the "Prev" button
        if (currentPage > 1) {
            System.out.print("Prev");
        }

        // always display the first page
        if (currentPage == 1) {
            System.out.print("    [1]");
        } else {
            System.out.print("    1");
        }

        // besides the first and last page, how many pages do we need to display?
        int how_many_times = 2 * x + 1;

        // we use the left and right to restrict the range that we need to display
        int left = Math.max(2, currentPage - 2 * x - 1);
        int right = Math.min(totalPages - 1, currentPage + 2 * x + 1);

        // the upper range restricted by left and right are more loosely than we need,
        // so we further restrict this range we need to display
        while (right - left > 2 * x) {
            if (currentPage - left < right - currentPage) {
                right--;
                right = right < currentPage ? currentPage : right;
            } else {
                left++;
                left = left > currentPage ? currentPage : left;
            }
        }

        // do we need display the left "..."
        if (left >= 3) {
            System.out.print("    ...");
        }

        // now display the middle pages, we display how_many_times pages from page left
        for (int i = 1, out = left; i <= how_many_times; i++, out++) {
            // there are some pages we need not to display
            if (out > right) {
                continue;
            }

            // display the actual page
            if (out == currentPage) {
                System.out.print("    [" + out + "]");
            } else {
                System.out.print("    " + out);
            }
        }

        // do we need the right "..."
        if (totalPages - right >= 2) {
            System.out.print("    ...");
        }

        // always display the last page
        if (currentPage == totalPages) {
            System.out.print("    [" + totalPages + "]");
        } else {
            System.out.print("    " + totalPages);
        }

        // if we are not at the last page, then display the "Next" button
        if (currentPage < totalPages) {
            System.out.print("    Next");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // printPageLinks(50, 3);
        help(500);
    }

    public static void test(int n) {
        for (int i = 1; i <= n; i++) {
            printPageLinks(n, i);
        }
        System.out.println("------------------------------");
    }

    public static void help(int n) {
        for (int i = 1; i <= n; i++) {
            test(i);
        }
    }

    public static void help(int from, int to) {
        for (int i = from; i <= to; i++) {
            test(i);
        }
    }

}