17

In Clojure, what would be the nicest way to have a sliding window over a (finite, not too large) seq? Should I just use drop and take and keep track of the current index or is there a nicer way I'm missing?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
pmf
  • 7,619
  • 4
  • 47
  • 77

3 Answers3

32

I think that partition with step 1 does it:

user=> (partition 3 1 [3 1 4 1 5 9])
((3 1 4) (1 4 1) (4 1 5) (1 5 9))
Jonas
  • 19,422
  • 10
  • 54
  • 67
3

If you want to operate on the windows, it can also be convenient to do this with map:

user=> (def a [3 1 4 1 5 9])
user=> (map (partial apply +) (partition 3 1 a))
(8 6 10 15)
user=> (map + a (next a) (nnext a))
(8 6 10 15)
Timothy Pratley
  • 10,586
  • 3
  • 34
  • 63
1

I didn't know partition could do this so I implemented it this way

(defn sliding-window [seq length]
  (loop [result ()
         remaining seq]
    (let [chunk (take length remaining)]
      (if (< (count chunk) length)
        (reverse result)
        (recur (cons chunk result) (rest remaining))))))
little-dude
  • 1,544
  • 2
  • 17
  • 33