I’m trying to write a function adjacents that returns a vector of a sequence’s adjacent pairs. So (adjacents [1 2 3]) would return [[1 2] [2 3]].
(defn adjacents [s]
(loop [[a b :as remaining] s
acc []]
(if (empty? b)
acc
(recur (rest remaining) (conj acc (vector a b))))))
My current implementation works for sequences of strings but with integers or characters the REPL outputs this error:
IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:494)
The problem here is in the first evaluation loop of
(adjacents [1 2 3]),ais bound to1andbto2. Then you ask ifbisempty?. Butempty?works on sequences andbis not a sequence, it is aLong, namely2. The predicate you could use for this case here isnil?:But, as @amalloy points out, this may fail to give the desired result if you have legitimate
nils in your data:See his comment for suggested implementation using lists.
Note that Clojure’s
partitioncan be used to do this work without the perils of defining your own: