2012-10-29 32 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

相关问题