File tree Expand file tree Collapse file tree 2 files changed +48
-2
lines changed
Expand file tree Collapse file tree 2 files changed +48
-2
lines changed Original file line number Diff line number Diff line change 727727 (cons (f (first* s1 val) (first* s2 val) (first* s3 val))
728728 (map-padded f val (rest s1) (rest s2) (rest s3)))))))
729729 ([f val c1 c2 c3 & colls]
730- (let [step (fn step [cs]
730+ (let [colls (vec (conj colls c3 c2 c1))
731+ step (fn step [cs]
731732 (lazy-seq
732733 (let [ss (mapv seq cs)]
733734 (when (some identity ss)
734735 (cons (apply f (mapv #(first* % val) ss))
735736 (step (mapv rest ss)))))))]
736- (step (conj colls c3 c2 c1))))))
737+ (step colls))))
738+
739+ (defn sequence-padded
740+ " Similar to `clojure.core/sequence`, except that it runs until all colls are
741+ exhausted, using `val` as the missing value for each exhausted coll."
742+ #_ {:clj-kondo/ignore [:unused-binding ]}
743+ ([xform val c1] (sequence xform c1))
744+ ([xform val c1 & colls]
745+ (let [colls (vec (cons c1 colls))
746+ f (xform (completing #(cons %2 %1 )))
747+ step (fn step [cs]
748+ (lazy-seq
749+ (let [ss (mapv seq cs)]
750+ (if (some identity ss)
751+ (let [res (apply f nil (mapv #(first* % val) ss))]
752+ (cond (reduced? res) (f (deref res))
753+ (seq? res) (concat res (lazy-seq (step (mapv rest ss))))
754+ :else (step (mapv rest ss))))
755+ (f nil )))))]
756+ (step colls)))))
Original file line number Diff line number Diff line change 572572 [:missing :missing 4 4 ]
573573 [:missing :missing :missing 5 ]]
574574 (take 6 (m/map-padded vector :missing [nil nil nil ] (range 4 ) (range 5 ) (range 10 )))))))
575+
576+ (deftest test-sequence-padded
577+ (is (= (map + (range 3 ) (range 4 ) (range 5 ) (range 10 ))
578+ [0 4 8 ]
579+ (take 3 (m/sequence-padded (map +) 0 (range 3 ) (range 4 ) (range 5 ) (range 10 )))))
580+ (is (= [0 4 8 19 28 35 36 37 38 39 ]
581+ (m/sequence-padded (map +) 10 (range 3 ) (range 4 ) (range 5 ) (range 10 ))))
582+ (is (= ()
583+ (m/sequence-padded (map +) 10 () () ())))
584+ (testing " laziness"
585+ (let [state (volatile! [])]
586+ (is (= [0 4 8 19 28 ]
587+ (take 5 (m/sequence-padded
588+ (map (fn [a b c d]
589+ (vswap! state conj [a b c d])
590+ (+ a b c d)))
591+ 10
592+ (range 3 ) (range 4 ) (range 5 ) (range 10 )))))
593+ (is (= [[0 0 0 0 ] [1 1 1 1 ] [2 2 2 2 ] [10 3 3 3 ] [10 10 4 4 ]]
594+ @state))))
595+ (testing " handles sequences with nils"
596+ (is (= [[nil 0 0 0 ] [nil 1 1 1 ] [nil 2 2 2 ]
597+ [:missing 3 3 3 ]
598+ [:missing :missing 4 4 ]
599+ [:missing :missing :missing 5 ]]
600+ (take 6 (m/sequence-padded (map vector) :missing [nil nil nil ] (range 4 ) (range 5 ) (range 10 )))))))
You can’t perform that action at this time.
0 commit comments