你怎么能在clojure中交错两个不同长度的向量

时间:2014-07-03 21:07:24

标签: clojure

使用n+1n成员交错两个向量的最简单方法是什么?

(def a [:a :c :e])
(def b [:b :d])
(interleave a b ); truncates to shortest list
[:a :b :c :d]

;what I would like. 
(interleave-until-nil a b)
[:a :b :c :d :e]

5 个答案:

答案 0 :(得分:6)

首先,将其余部分与反转的参数交错。

(cons (first a) (interleave b (rest a)))
;=> (:a :b :c :d :e)

答案 1 :(得分:2)

对于第二个,交错的colls得到所有butlast

(butlast (interleave a (conj b nil)))
;=> (:a :b :c :d :e)

答案 2 :(得分:2)

(defn interleave+ [& x] 
  (take (* (count x) (apply max (map count x))) 
    (apply interleave (map cycle x))))

(butlast (interleave+ [:a :c :e] [:b :d]))
=> (:a :b :c :d :e)

答案 3 :(得分:1)

将此视为懒惰seqs中的练习。我怀疑还有更优雅的方式。

(defn interleave-all
  "interleaves including remainder of longer seqs."
  [& seqs]
  (if (not-empty (first seqs))
    (cons (first (first seqs)) (lazy-seq (apply interleave-all (filter not-empty (concat (rest seqs) [(rest (first seqs))])))))))

答案 4 :(得分:1)

如果您想附加nil以始终具有相同的尺寸结果,则可以采用以下方法:

(defn interleave-all [& seqs]
  (reduce
   (fn [a i]
     (into a (map #(get % i) seqs)))
   []
   (range (apply max (map count seqs)))))

例如:

(interleave-all [:a] [:b :c])

输出:

[:a :b nil :c]

这可用于转置矩阵:

(defn matrix-transpose [input]
  (partition
   (count input)
   (apply interleave-all input)))

示例:

(matrix-transpose [[:a] [:b :c]])

输出:

[[:a :b] [nil :c]]

这可以用来对不同长度的列表进行表格输出(但是在需要固定尺寸以不插入任何内容的情况下,列表对于某些索引没有价值)。