附加到函数中的向量

时间:2015-05-02 06:43:33

标签: clojure

我有两个不同长度的列(向量)并且想要创建一个新的行向量(如果列有足够的元素)。我正在尝试创建一个新的向量(请参阅下面的失败尝试)。在Java中,这将涉及以下步骤:迭代向量,检查条件,附加到向量,返回向量。我在这里需要递归吗?我确信这不难解决,但它与程序代码非常不同。

(defn rowmaker [colA colB]
  "create a row of two columns of possibly different length"
  (let [mia (map-indexed vector colA)
        rows []]
    (doseq [[i elA] mia]
        ;append if col has enough elements
       (if (< i (count colA)) (vec (concat rows elA)))  ; ! can't append to rows
       (if (< i (count colB)) (vec (concat rows (nth colB i)))
    ;return rows   
    rows)))

预期的示例输入/输出

(rowMaker ["A1"] ["B1" "B2"])
; => [["A1" "B1“] [“" "B2"]]

4 个答案:

答案 0 :(得分:1)

(defn rowMaker [colA colB]
  "create a row from two columns"
  (let [ca (count colA) cb (count colB)
        c (max ca cb)
        colA (concat colA (repeat (- c ca) ""))
        colB (concat colB (repeat (- c cb) ""))]
    (map vector colA colB)))

答案 1 :(得分:1)

(defn rowmaker
  [cols]
  (->> cols
       (map #(concat % (repeat "")))
       (apply map vector)
       (take (->> cols
                  (map count)
                  (apply max)))))

答案 2 :(得分:0)

以下是给出示例的技巧:

(defn rowMaker [v1 v2]
  (mapv vector (concat v1 (repeat "")) v2))

(rowMaker ["A1"] ["B1" "B2"])
;[["A1" "B1"] ["" "B2"]]

但是,它没有相反的工作方式:

(rowMaker ["B1" "B2"] ["A1"])
;[["B1" "A1"]]

为了让它以两种方式工作,我们将不得不编写mapv的版本,只要任何序列都是肥沃的,就可以填充无菌序列。这是map的相应惰性版本,它也适用于无限序列:

(defn map-filler [filler f & colls]
  (let [filler (vec filler)
        colls (vec colls)
        live-coll-map (->> colls
                           (map-indexed vector)
                           (filter (comp seq second))
                           (into {}))
        split (fn [lcm] (reduce
                         (fn [[x xm] [i coll]]
                           (let [[c & cs] coll]
                             [(assoc x i c) (if cs (assoc xm i cs) xm)]))
                         [filler {}]
                         lcm))]
    ((fn expostulate [lcm]
       (lazy-seq
        (when (seq lcm)
          (let [[this thoses] (split lcm)]
            (cons (apply f this) (expostulate thoses))))))
     live-coll-map)))

我们的想法是为filler序列提供一个条目,其中包含后面的每个集合。因此,我们现在可以定义您所需的rowmaker函数:

(defn rowmaker [& colls]
  (apply map-filler (repeat (count colls) "") vector colls))

这将收集任意数量的集合,并将为耗尽的集合填写空白字符串。

(rowmaker ["A1"] ["B1" "B2"])
;(["A1" "B1"] ["" "B2"])

(rowmaker ["B1" "B2"] ["A1"])
;(["B1" "A1"] ["B2" ""])

有效!

答案 3 :(得分:0)

(defn make-row
  [cola colb r]
  (let [pad ""]
    (cond
      (and (not (empty? cola))
           (not (empty? colb))) (recur (rest cola)
                                       (rest colb)
                                       (conj r [(first cola) (first colb)]))
      (and (not (empty? cola))
           (empty? colb)) (recur (rest cola)
                                 (rest colb)
                                 (conj r [(first cola) pad]))
      (and (empty? cola)
           (not (empty? colb))) (recur (rest cola)
                                       (rest colb)
                                       (conj r [pad (first colb)]))
      :else r)))