2014-09-22 40 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。