clojure - 结合到结构以获得更平坦的结果

时间:2014-09-22 20:27:08

标签: clojure

我正在尝试组合两种结构:

(def acc [[1]])

(def pairs '((2 4)))

我想要以下结果:

'((1 2) (1 4))

我尝试了以下内容:

(map-indexed
  (fn [idx pair]
    (map (fn [itm]
      (concat (nth acc idx) (vector itm))) pair)) pairs)

但是这给了:

(((1 2) (1 4)))

我可以先打电话但是由于尝试了更大的名单,这会分崩离析。

例如,如果我有

(def acc '((1 2) (1 4)))

(def pairs '((5 1) (1 4)))

我希望结果是:

'((1 2 5) (1 2 1) (1 4 1) (1 4 4))

3 个答案:

答案 0 :(得分:2)

你想要一个算法,它接受两个输入序列的序列并执行此操作:

  1. 从每个输入序列中取一个序列,以便您有两个序列,s1s2
  2. elem中的每个s2生成s1并附加elem的序列
  3. 重复1.直到两个输入序列中的一个没有剩余序列
  4. 在Clojure中:

    (mapcat (fn [s1 s2]
               (map (fn [elem]
                      (conj s1 elem)) s2))
            acc pairs)
    

答案 1 :(得分:1)

在嵌套数据结构上进行映射时,for通常更简单。

user> 
(defn unfolder
  [acc pairs]
  (for [combination (map list acc pairs)
        tail (second combination)]
    (conj (vec (first combination)) tail)))

#'user/unfolder
user> (unfolder '((1 2) (1 4)) '((5 1) (1 4)))
([1 2 5] [1 2 1] [1 4 1] [1 4 4])

答案 2 :(得分:1)

注意:您的算法需要附加到集合 - 最好使用支持快速访问后面的集合类型(如vector

(def acc '([1 2] [1 4])) ;; notice the inner collections are vectors
(def pairs '([5 1] [1 4]))

(defn zipp
  [c1 c2]
  (mapcat (fn [c3 c4]
            (map (partial conj c3) c4)) ;; change this line for lists!
          c1
          c2))

(zipp acc pairs)
;; => ([1 2 5] [1 2 1] [1 4 1] [1 4 4])

如果您必须使用list,则可以将上面标记的行更改为:

(map (partial conj (into [] c3)) c4))

相当难看,IMO。