我如何在Clojure中维护2D向量的单个副本

时间:2019-05-30 00:04:11

标签: clojure

我想在整个课程中维护vector的单个副本。我必须递归多次更新vector。

 ;this is to update cell in vector
(defn to-plus [data x y]
 (update data y (fn [row] (apply str (assoc (vec row) x \+)))))

;here i am getting values in board and calling to-plus to update board
;now i need to maintain a single copy of board
(let [board (read-in-board "map.txt")]
(print-maze board)
(println(str (get-in board [1 4])))
(print-maze (to-plus board 1 4))
(println(to-plus board 1 4))) 

我正在尝试使用递归和随机游走来解决迷宫问题。我是Clojure的新手。

;Data is of type 
---#--###----
-#---#----##-
####-#-#-#-##
---#---#-#---
-+-####---##-
-#------#----
-############
------------@

3 个答案:

答案 0 :(得分:0)

如果需要紧密循环更新某些内容,则可以使用瞬态矢量。 Docs here。它们被设计为从单个Java线程“变异”并转变为持久数据结构,然后再从函数返回。它们纯粹是对持久性矢量的性能优化。首先使您的算法起作用,然后引入瞬态以使其更快。

答案 1 :(得分:0)

正如其他人已经回答的那样, Clojure 向量是不可变的。您有几种选择,

  1. 使用瞬态矢量。
  2. 使用原子。

使用瞬态,您的代码将如下所示,

@empty

使用原子,您的代码将如下所示,

(let [maze (transient [\* \* \* \*])]
  (assoc! maze
          1
          \#)
  (prn (persistent! maze)))

此打印,

(let [maze (atom [\* \* \* \*])]
  (prn @maze)
  (swap! maze
         assoc
         1
         \#)
  (prn @maze))

请注意,使用 atom 时,内部向量仍然是不可变的。您每次都用新的向量交换向量。因此,如果只考虑性能,请使用 transient

如果要更新深度嵌套的结构(请考虑数组的数组),请查看=> [\* \* \* \*] => [\* \# \* \*]

答案 2 :(得分:-1)

使用id m city 1 Jan SF 2 Feb NY 3 Mar LA 然后使用to-array-2daget

以上答案被L.F否决。在下面添加更多详细信息:

“ ...维护单个向量副本...” 回答:使用aset将不可变的嵌套向量转换为可变的2d数组。

“ ...多次更新向量...” 回答:使用to-array-2daget读取和更新创建的可变2d数组。