Уже есть несколько других ответов, но я хотел бы показать вам подход, который я использовал, чтобы решить его:
Во-первых, давайте посмотрим, как Stack Overflow обрабатывает обычные и крайние случаи. Каждая из моих страниц отображает 10 результатов, поэтому, чтобы узнать, что она делает для 1 страницы, найдите тег, который содержит менее 11 записей: удобство использования работает сегодня. Мы видим, что ничего не отображается, что имеет смысл.
Как насчет 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 ». Интересно, что мы видим, что само переполнение стека не очень хорошо справляется с этим краевым случаем: оно должно отображать « 1 2 ... 3 Next»
4 страницы? " 1 2 3 ... 4 Next", "Prev 1 2 3 ... 4 Next", "Prev 1 ... 2 3 4 Далее "и" Пред. 1 ... 3 4"
Наконец, давайте посмотрим на общий случай, N страниц: " 1 2 3 ... N Далее", "Предыдущая 1 2 3 ... N Следующая", " Предыдущая 1 ... 2 3 4 ... N Следующая "," Предыдущая 1 ... 3 4 5 ... N Следующая "и т. Д.
Давайте обобщим на основании того, что мы видели:
Алгоритм, похоже, имеет следующие общие черты:
- Если мы не на первой странице, отобразить ссылку на предыдущий
- Всегда отображать номер первой страницы
- Всегда отображать номер текущей страницы
- Всегда отображать страницу до этой страницы и страницу после этой страницы.
- Всегда отображать номер последней страницы
- Если мы не на последней странице, отобразить ссылку на Далее
Давайте проигнорируем крайний край одной страницы и сделаем хорошую первую попытку алгоритма: (Как уже упоминалось, код для фактической распечатки ссылок будет более сложным. Представьте себе, где мы размещаем номер страницы, Пред или След в качестве вызова функции, которая вернет правильный 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
Надеюсь, это поможет!