Reputation: 18827
How can I iterate the elements of a collection in Clojure so I can access the previous, current and next values in every iteration.
With the following vector:
[1 2 3 4]
I would like to have access to the following values in each iteration:
[nil 1 2]
[1 2 3]
[2 3 4]
[3 4 nil]
Upvotes: 5
Views: 1294
Reputation: 70211
I'd recommend the partitioning technique, but another trick is to map
over staggered instances of the same sequence:
(let [s [1 2 3 4]]
(map vector (cons nil s)
s
(concat (drop 1 s) [nil])))
-> ([nil 1 2] [1 2 3] [2 3 4] [3 4 nil])
Upvotes: 4
Reputation: 9266
Here is a loop/recur
implementation utilizing destructoring.
(let [s [1 2 3 4]]
(loop [[prev & [cur nxt :as more]] (cons nil s)
result []]
(if (seq more)
(recur more (conj result [prev cur nxt]))
result)))
Upvotes: 3
Reputation: 10484
One way to do it is by concat
ting nil
before and after the collection and partition
ing it by elements of 3 with a step size of 1.
(def c [1 2 3 4])
(def your-fn println) ;; to print some output later
(map your-fn
(map vec (partition 3 1 (concat [nil] c [nil]))))
(You can remove the map vec
part if it is also fine if the elements are a LazySeq instead of a vector.)
Which prints:
[nil 1 2]
[1 2 3]
[2 3 4]
[3 4 nil]
Upvotes: 9