Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm / pseudo-code to create paging links?

Can someome provide code or pseudo-code for how the paging links on StackOverflow are generated?

I keep racking my brain but can't think of a decent way to build the dynamic links that always show the 2 pages around the current, plus the first and last.

Example: 1 ... 5 6 7 ... 593

like image 916
Geoff Avatar asked Sep 04 '08 19:09

Geoff


People also ask

How do you write pseudocode for an algorithm?

Writing in pseudocode is similar to writing in a programming language. Each step of the algorithm is written on a line of its own in sequence. Usually, instructions are written in uppercase, variables in lowercase and messages in sentence case. In pseudocode, INPUT asks a question.

What is the algorithm in the pseudo code used for?

The purpose of using pseudocode is an efficient key principle of an algorithm. It is used in planning an algorithm with sketching out the structure of the program before the actual coding takes place. Pseudocode is understood by the programmers of all types.

What do you mean by pseudo code?

Pseudocode (pronounced SOO-doh-kohd) is a detailed yet readable description of what a computer program or algorithm must do, expressed in a formally-styled natural language rather than in a programming language. Pseudocode is sometimes used as a detailed step in the process of developing a program.


1 Answers

There are several other answers already, but I'd like to show you the approach I took to solve it: First, let's check out how Stack Overflow handles normal cases and edge cases. Each of my pages displays 10 results, so to find out what it does for 1 page, find a tag that has less than 11 entries: usability works today. We can see nothing is displayed, which makes sense.

How about 2 pages? Find a tag that has between 11 and 20 entries (emacs works today). We see: "1 2 Next" or "Prev 1 2", depending on which page we're on.

3 pages? "1 2 3 ... 3 Next", "Prev 1 2 3 Next", and "Prev 1 ... 2 3". Interestingly, we can see that Stack Overflow itself doesn't handle this edge case very well: it should display "1 2 ... 3 Next"

4 pages? "1 2 3 ... 4 Next", "Prev 1 2 3 ... 4 Next", "Prev 1 ... 2 3 4 Next" and "Prev 1 ... 3 4"

Finally let's look at the general case, N pages: "1 2 3 ... N Next", "Prev 1 2 3 ... N Next", "Prev 1 ... 2 3 4 ... N Next", "Prev 1 ... 3 4 5 ... N Next", etc.

Let's generalize based on what we've seen: The algorithm seems to have these traits in common:

  • If we're not on the first page, display link to Prev
  • Always display the first page number
  • Always display the current page number
  • Always display the page before this page, and the page after this page.
  • Always display the last page number
  • If we're not on the last page, display link to Next

Let's ignore the edge case of a single page and make a good first attempt at the algorithm: (As has been mentioned, the code to actually print out the links would be more complicated. Imagine each place we place a page number, Prev or Next as a function call that will return the correct 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

This function works ok, but it doesn't take into account whether we're near the first or last page. Looking at the above examples, we only want to display the ... if the current page is two or more away.

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

As you can see, we have some duplication here. We can go ahead and clean that up for readibility:

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

There are only two problems left. First, we don't print out correctly for one page, and secondly, we'll print out "1" twice if we're on the first or last page. Let's clean those both up in one go:

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

Actually, I lied: We have one remaining issue. When you have at least 4 pages and are on the first or last page, you get an extra page in your display. Instead of "1 2 ... 10 Next" you get "1 2 3 ... 10 Next". To match what's going on at Stack Overflow exactly, you'll have to check for this situation:

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

I hope this helps!

like image 56
Bill Avatar answered Oct 01 '22 04:10

Bill