从Clojure中的Atom筛选贴图列表

从Clojure中的Atom筛选贴图列表,clojure,Clojure,我正在开发一个迷你社交媒体API,允许用户插入一个新的配置文件,将两个配置文件连接在一起(比如朋友),然后根据“我朋友的朋友”规则接收推荐 现在我正在尝试为概要文件创建API 我有一个原子,它有一个映射列表,每个配置文件对应一个 (def profiles (atom ())) (defn create [request] (swap! profiles conj {:id (get-in request [:body "id"]) :name (ge

我正在开发一个迷你社交媒体API,允许用户插入一个新的配置文件,将两个配置文件连接在一起(比如朋友),然后根据“我朋友的朋友”规则接收推荐

现在我正在尝试为概要文件创建API

我有一个原子,它有一个映射列表,每个配置文件对应一个

(def profiles (atom ()))

(defn create [request]
 (swap! profiles conj {:id (get-in request [:body "id"])
                    :name (get-in request [:body "name"])
                    :age (get-in request [:body "age"])
                    :recommendable (get-in request [:body "recommendable"])
                    :friends (list) 
})
(created "")
)
当我遇到问题时,我正试图为API的GetHTTP动词开发FindByID。如何从所述列表中的映射中获取值,以便对其应用函数

例如,在这里,我试图使用filter函数仅返回包含给定id的映射。但我一直收到一个错误:

(defn find-by-id [id]
  (filter #(= (:id %) id) profiles)
)

Dont know how to create ISeq from: clojure.lang.Atom
在我看来,过滤器不适用于原子

删除时也会发生同样的情况:

(defn delete-by-id [id]
 (swap! profiles (remove #(= (:id %) id) profiles))
)
当我尝试使用@profiles时,结果得到一个空数组。更糟糕的是,当我尝试使用REPL的过滤函数时,它工作得很好

这让我想知道我在这里错过了什么

谁能告诉我发生了什么事


提前感谢。

第一个失败是因为,正如它所说,原子不是一个序列,这是
过滤器所期望的

您需要先从atom中获取序列,然后才能
筛选它:

; I'm dereferencing the atom using @ to get the list of profiles that it holds
(defn find-by-id [id]
  (filter #(= (:id %) id) @profiles))
但请注意,这并不是最优的。您依赖于
配置文件的状态,该状态可能在看似随机的时间发生变化(如果您有异步进程
交换!
ping它)。这可能会使调试复杂化,因为在数据传递到
过滤器之前,您无法对其进行良好的处理。函数依赖于
profiles
作为一个原子也是不好的,因为这与它的功能无关,以后可能会更改设计。让这个函数完全依赖于它的参数,而不了解原子,这将是未来的证明:

(defn find-by-id [id profiles]
  (filter #(= (:id %) id) profiles))

; Then call it like this. I renamed your atom here
(find-by-id some-id @profile-atom)

您的第二个示例失败,因为
swap接受函数作为其第二个参数。我想你是想用
reset,它会更改原子的值,而不管原子以前是什么:

(defn delete-by-id [id]
  (reset! profiles (remove #(= (:id %) id) @profiles)))
尽管如此,这也不是最优的。如果您想基于以前的状态更新atom,请使用
swap并提供更新功能:

(defn delete-by-id [id]
  (swap! profile-atom (fn [profiles] (remove #(= (:id %) id)) profiles)))
或者更简洁地说:

(defn delete-by-id [id]
  (swap! profile-atom (partial remove #(= (:id %) id))))

我正在部分应用
remove
来生成一个函数。原子的旧状态作为最后一个参数传递给
remove

非常感谢你的帮助。但是“按id查找”一点结果也没有。删除并不是从列表中删除地图。此外,您还建议我将概要文件列表转换为函数的参数,但由于这是一个API,因此我的handler.clj文件只有路由,而整个代码都在profile.clj文件中。如果我将概要文件作为参数传递,我将在哪里声明它?因为将其留在profile.clj中会使其在handler.clj中不可访问,如果是另一种情况,则我的create函数将无法更新配置文件列表。@LeonardoMarinho由于筛选和删除不起作用,ID必须不是您要搜索的内容。你需要仔细检查你传递的ID和地图上的ID。对于第二个问题,您可以将其包装到另一个函数中。类似于
(fn[profile atom](按id查找某个id@profile atom))
。我不确定这是否回答了你的问题。