Skip to content

Instantly share code, notes, and snippets.

@djui
Last active December 15, 2015 14:49
Show Gist options
  • Select an option

  • Save djui/5277639 to your computer and use it in GitHub Desktop.

Select an option

Save djui/5277639 to your computer and use it in GitHub Desktop.
gapmap function for Clojure
(defn gapmap
"Returns a lazy sequence consisting of the result of applying f to all
adjacent values of coll. f should be a function of 2 arguments. If coll
contains less than 2 items, it is returned and f is not called."
{:added "1.6"}
([f coll]
(if-let [r (next coll)] ; at least two items?
(lazy-seq (gapmap-internal f (first coll) r))
coll)))
(defn- gapmap-internal
[f x coll]
(if-let [y (first coll)]
(cons (f x y) (gapmap-internal f y (next coll)))))
;;------------------------------------------------------------------------------
;; Tests
(use 'clojure.test)
(deftest gapmap-tests
(is (= (gapmap + []) []) "Ignore empty lists")
(is (= (gapmap + [0]) [0]) "Ignore lists with only one item")
(is (= (gapmap + [0 0]) [0]))
(is (= (gapmap + [0 1 0]) [1 1]))
(is (= (gapmap + [0 1 1 0]) [1 2 1]))
(is (= (gapmap + [0 1 2 1 0]) [1 3 3 1]))
(is (false? (realized? (gapmap + (range))))) "Assert lazy sequence")
(gapmap-tests)
;;------------------------------------------------------------------------------
;; Example
=> (take 5 (iterate #(gapmap + (concat [0] % [0])) [1]))
((1) (1 1) (1 2 1) (1 3 3 1) (1 4 6 4 1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment