2017-01-29 47 views
2

如何在Clojure中迭代集合中的元素,以便可以訪問每次迭代中的前一個,當前值和下一個值。如何迭代集合並訪問每次迭代中的前一個,當前和下一個值?

用下面的載體:

[1 2 3 4] 

我想有機會獲得以下值在每個迭代:

[nil 1 2] 
[1 2 3] 
[2 3 4] 
[3 4 nil] 
+0

遞歸函數,有多個參數和它們作爲參數傳遞給復發嗎?感覺就像我誤解了你的問題。 –

+0

@DavidBern你可以把代碼樣本? – eliocs

+1

它的教育閱讀clojure社區的問題和答案。我覺得比較愚蠢。我想到的解決方案是: (循環[prev nil,[current&next] [0,1,2,3,4,5,6,7]](if(nil?next)current(do (println next)(當前發生的下一個)))) 當看着Erwin給出的答案時,我驚訝於剩下多少東西來學習:) –

回答

5

一種方式做到這一點是concatnil前後該集合以及具有3的步長1的元素。

(def c [1 2 3 4]) 
(def your-fn println) ;; to print some output later 
(map your-fn 
    (map vec (partition 3 1 (concat [nil] c [nil])))) 

(可以如果它也是細如果元件是LazySeq代替矢量的取出map vec一部分。)

它打印:

[零1 2]
[1 2 3]
[2 3 4]
[3 4零]

+0

不知道'partition'函數真的有用! – eliocs

3

這裏是一個loop/recur實現利用destructoring。

(let [s [1 2 3 4]] 
    (loop [[prev & [cur nxt :as more]] (cons nil s) 
     result []] 
    (if (seq more) 
     (recur more (conj result [prev cur nxt])) 
     result))) 
+0

發現它很難理解這個解決方案 – eliocs

+2

@eliocs一旦你已經內化析構,這是非常直觀的掌握,但如果你需要一個通用的可重用解決方案,我會建議一個更多的功能的結構像其他兩個答案。 –

+0

終於讓我的腦袋變得非常酷 – eliocs

3

我推薦的分區技術,但另一個竅門是map在同一序列的交錯實例:

(let [s [1 2 3 4]] 
    (map vector (cons nil s) 
       s 
       (concat (drop 1 s) [nil]))) 

-> ([nil 1 2] [1 2 3] [2 3 4] [3 4 nil]) 
相關問題