Idiom for Fill Sequences

To set a sequence with some value, this is what I came up with:

(defn pad [n coll val] (take n (concat coll (repeat val)))) (pad 10 [1 2 3] nil) ; (1 2 3 nil nil nil nil nil nil nil) 

I am curious if there is a shorter idiom that does this already and possibly more efficiently.

+6
source share
2 answers

Yes, this is an idiomatic way to jump to the filling sections of a sequence. Actually, this code is very similar to part of the partition function in clojure.core , the difference is that partition does not accept a single padding value and instead asks for the sequence:

core.clj:

 ([n step pad coll] (lazy-seq ... (list (take n (concat p pad)))))))) 

You can get the same results by passing a collection of add-ons for sharing:

 user> (defn pad [n coll val] (take n (concat coll (repeat val)))) #'user/pad user> (pad 10 [1 2 3] nil) (1 2 3 nil nil nil nil nil nil nil) user> (first (partition 10 10 (repeat nil) [1 2 3])) (1 2 3 nil nil nil nil nil nil nil) 
+5
source

There is a lazy version of the fill function:

 (defn lazy-pad "Returns a lazy sequence which pads sequence with pad-value." [sequence pad-value] (if (empty? sequence) (repeat pad-value) (lazy-seq (cons (first sequence) (lazy-pad (rest sequence) pad-value))))) 

You can use it as a regular endless lazy collection:

 (take 5 (lazy-pad [1 2 3] :pad)) => (1 2 3 :pad :pad) 

IMO this is more elegant. You can also use it with other functions that expect a lazy sequence that doesn't work if you need to specify an upfront length:

 (partition 2 (interleave [1 2 3 4] (lazy-pad [:a] :pad))) => ((1 :a) (2 :pad) (3 :pad) (4 :pad)) 
0
source

Source: https://habr.com/ru/post/979020/


All Articles