Skip to content

Instantly share code, notes, and snippets.

@samflores
Last active December 1, 2015 12:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samflores/38a7e6cd685226f86a9f to your computer and use it in GitHub Desktop.
Save samflores/38a7e6cd685226f86a9f to your computer and use it in GitHub Desktop.
(ns pagination.core)
(defn slice [total size center]
(range
(max 1 (- center size))
(inc (min total (+ center size)))))
(defn intersect? [s1 s2] (<= (first s2) (inc (last s1))))
(defn group-slices [slices]
(reduce
#(if (intersect? (last %1) %2)
(update-in %1 [(dec (count %1))]
(fn [l] (->> %2 (apply conj l) distinct sort)))
(conj %1 %2))
[(first slices)]
(rest slices)))
(defn pagination [{:keys [total current padding]}]
(group-slices
(map
(partial slice total (or padding 2))
(distinct [1 current total]))))
;; (pagination {:total 20 :current 7 :padding 2})
;; => [[1 2 3] [5 6 7 8 9] [18 19 20]]
(ns pagination.core-test
(:require [clojure.test :refer [deftest is]]
[pagination.core :refer [slice group-slices pagination]]))
(deftest slice-at-begin
(is (= (slice 10 2 1) [1 2 3])))
(deftest slice-at-end
(is (= (slice 10 2 10) [8 9 10])))
(deftest slice-at-center
(is (= (slice 10 2 5) [3 4 5 6 7])))
(deftest group-without-intersection
(is (= (group-slices [[1 2 3] [7 8 9] [12 13 14]])
[[1 2 3] [7 8 9] [12 13 14]])))
(deftest group-with-intersection
(is (= (group-slices [[1 2 3] [2 3 4] [7 8 9]])
[[1 2 3 4] [7 8 9]])))
(deftest group-with-adjacent-slices
(is (= (group-slices [[1 2 3] [4 5 6] [7 8 9]])
[[1 2 3 4 5 6 7 8 9]])))
(deftest pagination-with-current-at-begin
(is (= (pagination {:total 10 :current 1 :padding 2})
[[1 2 3] [8 9 10]])))
(deftest pagination-with-current-at-end
(is (= (pagination {:total 10 :current 10 :padding 2})
[[1 2 3] [8 9 10]])))
(deftest pagination-with-current-at-middle
(is (= (pagination {:total 20 :current 7 :padding 2})
[[1 2 3] [5 6 7 8 9] [18 19 20]])))
(deftest pagination-with-intersection-slices
(is (= (pagination {:total 20 :current 4 :padding 2})
[[1 2 3 4 5 6] [18 19 20]])))
(deftest pagination-with-small-set
(is (= (pagination {:total 5 :current 1 :padding 2})
[[1 2 3 4 5]])))
(deftest pagination-with-default-padding
(is (= (pagination {:total 20 :current 5})
[[1 2 3 4 5 6 7] [18 19 20]])))
(deftest pagination-with-bigger-padding
(is (= (pagination {:total 20 :current 5 :padding 5})
[[1 2 3 4 5 6 7 8 9 10] [15 16 17 18 19 20]])))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment