3

我想按号码删除房间。如您所见,房间是原子列表并包含原子。我遇到了一个异常:IllegalArgumentException 不知道如何从以下位置创建 ISeq:core.main$delete_room_by_id$fn__7541 clojure.lang.RT.seqFrom (RT.java:487)

我有这个代码:

(comment ------------- * DATA * ----------------- )
(def rooms "atomic list of atoms - rooms" (atom '()))

(comment ------------- * UTILS * ----------------- )

(defn enter-value [message]
     (do (println message) (read-line)))

(comment ------------- * ADD ROOM * ----------------- )

(defn save-room "The function that will save provided room." 
     [number num-of-beds price]
     (swap! rooms conj (atom {:number number 
                              :num-of-beds num-of-beds
                              :price price 
                              :is-ocupated false})))

(defn enter-room "This function will create room based on user input." []
     (let [number (enter-value "Number...")
           num-of-beds (enter-value "Number of beds...")
           price (enter-value "Price...")]
       (save-room number num-of-beds price)))

(comment ------------- * DELETE ROOM * ----------------- )

(defn delete-room-by-number "Delete room by number."
     [number]
     (swap! rooms remove #(not (= (:number @%) number))))

我认为交换!函数不要像我想要的那样为删除函数设置参数。我认为最后的命令是:(删除房间#(不是(=(:数字@%)数字)))。这不好,因为我必须取消引用 @rooms 之类的房间并将其作为删除函数的第二个参数传递。

感谢您阅读本文。

4

1 回答 1

7

两个函数有错误。save-room 中的值不应该是原子中的映射,而只是映射,因为否则您将原子保存在原子中。也 delete-by-room-number 包含一个错误,匿名函数没有正确编写。

(defn save-room "The function that will save provided room." 
           [number num-of-beds price]
           (swap! rooms conj {:number number :num-of-beds num-of-beds :price price :is-ocupated false}))

(defn delete-room-by-number [num]
     (swap! rooms #(remove (fn [room] (= (:number room) num)) %)))

更新:

更常见的做法是将不可变的、可能嵌套的数据结构存储在 atom/ref 等中。更好的选择可能是不使用列表,而是使用矢量或地图,如下所示:

(def room-map {1 {:nums-of-beds 2 :price 30}, 2 {:nums-of-beds 4 :price 60}})

这样您就可以使用房间号作为密钥。这样你就永远不会有重复的房间号,因为地图键必须是唯一的。

您可以使用 assoc-in、update-in 等更新地图:

(def new-room-map (assoc-in room-map [2 :nums-of-beds] 40))

新房间地图的价值:{1 {:nums-of-beds 2, :price 30}, 2 {:nums-of-beds 40, :price 60}}

如果您要获取房间的地图表示,请将函数 assoc-in 与 swap 结合使用!并且您的房间地图的更新版本将存储在 atom 中。如果您无法理解这一点,我建议您阅读有关这些功能的更多信息:

http://clojuredocs.org/clojure_core/clojure.core/swaphttp://clojuredocs.org/clojure_core/clojure.core/assoc-in

于 2012-12-15T08:42:35.177 回答