clojure - Overlapping partition in core.async -
in clojure can overlapping partitions of collection tuning step
argument partition
:
(partition 3 1 (range 20)) ;; ((0 1 2) (1 2 3) (2 3 4) (3 4 5) ...)
core.async have partition function since doesn't accept step argument, can't overlapping partitions:
(let [c (chan)] (go (doseq [n (range 20)] (>! c n))) (go-loop [p (async/partition 3 c)] (when-let [v (<! p)] (prn v) (recur p)))) ;;[0 1 2] ;;[3 4 5] ;;[6 7 8]
i realise having mean being able read same value channel more once. i'm aware create own function reads many values channel want , build own partitions.
however wondering if there way achieve core api provided core.async.
ps. sliding-buffer
doesn't trick can't peek @ whole buffer @ once.
one way of doing create function reads channel, buffers values , puts new channel. i'm not sure how idiomatic though.
for example, function below put!
vector output channel whenever required n
items have been read input channel, skipping step
items after every output.
(defn stepped-partition [in n step] (let [out (chan)] (go-loop [buffer []] (when-let [v (<! in)] (let [new-buffer (conj buffer v)] (if (= (count new-buffer) n) (do (put! out new-buffer) (recur (subvec new-buffer step))) (recur new-buffer))))) out)) (def original (chan)) (def partitioned (stepped-partition 3 2)) (go-loop [] (when-let [v (<! partitioned)] (println v) (recur))) (async/onto-chan original [1 2 3 4 5 6 7 8 9]) ;=> [1 2 3] ;=> [3 4 5] ;=> [5 6 7] ;=> [7 8 9]
Comments
Post a Comment