Reputation: 77
I am working on a function that will split a sequence of dates (or anything else) into a number of sequences contained within a vector based on a given number x.
(date1 date2 date3 date4 date5 date6 date7)
So given the list of dates above and passing in the variable 2 it will produce the vector below.
[(date1 date2) (date3 date4) (date5 date6) (date7)]
The code I have so far is below but all it returns is a vector containing nil.
(defn date-splitter [date-count dates x]
(loop [i date-count, current-split dates, split-dates (vector)]
(if (<= i x)
(conj split-dates (get current-split 1))
(let [s (split-at x current-split)]
(recur (int (- i x)) (get s 1) (conj split-dates (get s 0)))))))
I have also had a look at the split-with function, thinking that I could use it to split the sequence when the modulus of the index divided by x is zero, but I haven't had any luck with this.
Any help would be greatly appreciated.
David.
Upvotes: 2
Views: 2512
Reputation: 6956
Take a look at split
's cousin partition
=> (partition-all 2 '(1 2 3 4 5 6 7))
((1 2) (3 4) (5 6) (7))
If you want to do index based operations, you can use map-indexed
and keep-indexed
.
=> (map-indexed (fn [idx itm] [(Math/floor (/ idx 2)) itm]) [1 2 3 4 5 6 7])
([0.0 1] [0.0 2] [1.0 3] [1.0 4] [2.0 5] [2.0 6] [3.0 7])
In FP, non-index based operations are usually the better option though. Index based solutions can be considered code smell.
There's several ways of doing partition the FP way without index. Ankur's is a great example of how to solve this if partition-all wouldn't have been in core clojure.
Upvotes: 5
Reputation: 33637
(defn date-splitter [n v]
(if (not (seq v))
[]
(lazy-cat [(take n v)] (date-splitter n (drop n v)))))
user=> (date-splitter 3 [1,2,3,4])
((1 2 3) (4))
Upvotes: 2