Skip to content

Instantly share code, notes, and snippets.

@BideoWego
Created April 19, 2017 21:16
Show Gist options
  • Save BideoWego/762938724273e7651e335a70e76e0a87 to your computer and use it in GitHub Desktop.
Save BideoWego/762938724273e7651e335a70e76e0a87 to your computer and use it in GitHub Desktop.
A simple an effective pagination algorithm with an O(n) time complexity where n is the number of pages in the range `(current - delta) ... (current + delta) + 2`
// Pagination algorithm
// Refactored by https://github.com/BideoWego
// Originally from:
// https://gist.github.com/kottenator/9d936eb3e4e3c3e02598
function pagination(current, max, delta) {
// Return nada if we got
// no pages
if (!max) {
return [];
}
// Find page display range
let left = current - delta;
let right = current + delta;
// Initialize page list
// with first page
let pages = [1];
// Find max between next page `2`
// and the beginning of the page
// range around the current page
// and set it to our start
let start = Math.max(2, left)
// Find the min between the right
// and the max pages
// and set it to our stop
let stop = Math.min(right, max);
// Begin iterating at the min
// and stop when we get to the right
// or when we get to max
for (let i = start; i <= stop; i++) {
// If the current i is in our display
// range push it onto the array
let isInRange = i >= left && i <= right;
if (isInRange) {
pages.push(i);
}
}
// If the last element in our array
// is not the last page number push it
if (pages[pages.length - 1] !== max) {
pages.push(max)
}
// Initialize last index
let last = 0;
// Adding ellipsis
// Start at 1 since last is set to 0
for (let i = 1; i < pages.length; i++) {
// Get previous page number
let a = pages[last];
// Get current page number
let b = pages[i];
// Get difference between them
let diff = b - a;
// If there is a difference
// larger than 1
if (diff > 1) {
// Close the gap if it is
// a single space
if (diff === 2) {
pages.splice(i, 0, b - 1);
} else {
// Else and ellipsis
pages.splice(i, 0, '...');
}
}
// Set last index
// to current
last = i;
}
// Return page list
return pages;
}
// Test the algo
if (require.main === module) {
for (let i = 0; i < 1000; i++) {
console.log(`Testing max = ${ i }`);
for (let current = 1, max = i; current <= max; current++) {
let range = pagination(current, max, 4);
console.log(`Selected page: ${ current }:`, range);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment