填充序列的习语

时间:2014-12-03 01:42:19

标签: clojure sequences

要填写具有某些价值的序列,这就是我提出的:

(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)

我很好奇是否有一个较短的成语,已经这样做,也许更有效率。

2 个答案:

答案 0 :(得分:7)

是的,这是一种关于序列填充分区的惯用方法。事实上,代码与part of the partition function in clojure.core非常相似,不同之处在于partition不假设单个填充值而是要求序列:

core.clj:

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

您可以通过将填充集合传递给分区来获得相同的结果:

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)

答案 1 :(得分:0)

这是填充函数的惰性版本:

(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)))))

你可以像常规的无限懒惰集合一样使用它:

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

IMO这种方式更优雅。您还可以将其与其他期望延迟序列的函数一起使用,如果您必须预先指定长度,则该函数不起作用:

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