2014-09-22 71 views
0

我想2种结构结合起来:的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)) 
+2

你期待 “大名单” 什么样的行为目前尚不清楚。此外,您发布的代码将无法编译('acc'无法解析)。 – 2014-09-22 20:54:50

+0

@ A.Webb我已经更新了这个问题,让我知道如果它仍然不清楚。 – dagda1 2014-09-22 21:16:58

回答

2

你想要一个算法,需要序列的两个输入序列,并做到这一点:

  1. 采取从每个输入序列的一个序列,使你有两个序列,s1s2
  2. 对于每个elems2产生一个s1的序列,其中elem附加到它
  3. 重复1.直到两个输入序列中的一个没有剩余序列

在Clojure中:

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

当我在@dagda1的'acc'和'pairs'上运行它时,它将它们想要的项目放在列表头部。否则它看起来不错。 – paul 2014-09-23 19:46:21

+0

这是真的。他提供了一个“acc”作为矢量,另一个作为列表的例子。我决定写矢量版本的实现,因为向矢量附加值具有更好的性能特征。 – 2014-09-23 20:24:22

+0

啊,是的,有一个矢量 - 我只在列表版本上运行它。谢谢你澄清。 – paul 2014-09-23 20:40:21

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]) 
+1

项目缺少一层嵌套。([对'((2 4))元素对项目[[1]]项目项目] [项目元素]) – GregA100k 2014-09-22 20:52:03

+0

编辑,谢谢 – noisesmith 2014-09-22 21:04:55

+0

我已经更新了问题,我不认为我可以用于第二个例子。 – dagda1 2014-09-22 21:19:32

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。