2012-10-29 27 views
6

我在下班後學習clojure,我通過製作一個小遊戲(愛quil庫)來讓我熟悉clojure在特定和FP中的不同方面。因此,我的遊戲世界存在三維地圖數據結構網格(地圖矢量矢量矢量)。我想在三維空間(地圖)中的每個點上進行迭代,並在條件滿足時更改數據。這是我最初的解決方案:您可以將數據傳遞給(for ...)中的下一次迭代嗎?

(遊戲中的數據結構是遊戲狀態(圖))

(defn soil-gen [game] 
    (let [world-x (game :world-x) 
     world-y (game :world-y) 
    world-z (game :world-z)] 
     (for [x (range world-x) 
      y (range world-y) 
      z (range world-z) 
      :when (> z (* world-z (rand)))] 
     (assoc-in game [:world x y z :type] :soil)))) 

但這返回每個迭代的結果(我的比賽狀態數據結構)的列表,而不是的一個遊戲數據結構。我應該能夠將每次迭代的結果返回給for。類似loop/recur可能但我認爲你不能將recur與for結合起來。

有人有線索嗎?

感謝

回答

8

你可以做的是使用reducefor如下圖所示:

(defn soil-gen [game] 
    (let [world-x (game :world-x) 
     world-y (game :world-y) 
    world-z (game :world-z)] 

    (reduce (fn [g [x y z]] (assoc-in g [:world x y z :type] :soil))) 
      game 
      (for [x (range world-x) 
        y (range world-y) 
        z (range world-z) 
       :when (> z (* world-z (rand)))] 
       [x y z])))) 
+0

正是我想要的,謝謝 – user1782011

2

你可能想使用類似reduce通過每次迭代的累積結果。

簡化的例子:

(reduce 
    (fn [m val] (assoc m val (str "foo" val))) 
    {}    ;; initial value for m 
    (range 5))  ;; seqence of items to reduce over 

=> {4 "foo4", 3 "foo3", 2 "foo2", 1 "foo1", 0 "foo0"} 

reduce通常是非常有用的,從而每當在功能編程的「累計值」的一些概念。它還具有非常高效的優點。

+0

感謝上減少額外的信息。 – user1782011

相關問題