Last active
May 16, 2019 17:58
-
-
Save vbarbarosh/51875ff0cf2265653c9425eccced9b66 to your computer and use it in GitHub Desktop.
js_pager_numerate_ellipsis – Generate page numbers like Amazon does https://codescreens.com
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generate page numbers like Amazon does | |
// | |
// The algorithm: | |
// 1) Represent a result as three ranges: first, middle, last | |
// 2) Merge three ranges into single array, sort then remove duplicates. | |
// 3) Insert N between two adjacent numbers with values N-1 and N+1. | |
// 4) Insert ... between two adjacent numbers with difference more than 1. | |
// | |
// Inspired by https://gist.github.com/kottenator/9d936eb3e4e3c3e02598 | |
function pager_numerate_ellipsis(active, total) | |
{ | |
// 1|2|3 | |
// 1|...|18|19|20 | |
// 1|...|5|6|7|...|20 | |
const c = active - 3; | |
const d = active + 4; | |
return [1, ...range(c, d), total].reduce(function (ret, no, i, src) { | |
if (ret.length && ret[ret.length-1] >= no) { | |
return ret; | |
} | |
if (i && src[i-1] + 1 == no - 1) { | |
ret.push(no - 1); | |
} | |
else if (i && src[i-1] + 1 < no) { | |
ret.push('...'); | |
} | |
ret.push(no); | |
return ret; | |
}, []).map(v => v == active ? `[${v}]` : v); | |
} | |
function range(begin, end) | |
{ | |
return Array(end - begin).fill(0).map((v,i) => i + begin); | |
} | |
// __CODESCREEN_END__ | |
const expected = ` | |
[1] 2 3 4 ... 15 | |
1 [2] 3 4 5 ... 15 | |
1 2 [3] 4 5 6 ... 15 | |
1 2 3 [4] 5 6 7 ... 15 | |
1 2 3 4 [5] 6 7 8 ... 15 | |
1 2 3 4 5 [6] 7 8 ... 15 | |
2 3 4 5 6 [7] 8 9 10 11 | |
3 4 5 6 7 [8] 9 10 11 12 | |
4 5 6 7 8 [9] 10 11 12 13 | |
5 6 7 8 9 [10] 11 12 13 14 | |
6 7 8 9 10 [11] 12 13 14 15 | |
6 7 8 9 10 11 [12] 13 14 15 | |
6 7 8 9 10 11 12 [13] 14 15 | |
6 7 8 9 10 11 12 13 [14] 15 | |
1 ... 12 13 14 [15] | |
`.trim().split('\n'); | |
for (let i = 0; i < 15; ++i) { | |
const str = pager_numerate_ellipsis(i+1, 15, 10).join(' '); | |
console.log(str == expected[i], str); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment