如何在Clojure中向数组映射添加元素?
如何在Clojure中向数组映射添加元素?我尝试使用assoc,但没有添加?我基本上希望为条目数组映射中的任何缺失项设置默认值0如何在Clojure中向数组映射添加元素?,clojure,Clojure,如何在Clojure中向数组映射添加元素?我尝试使用assoc,但没有添加?我基本上希望为条目数组映射中的任何缺失项设置默认值0 (defn create-entry [doc] (let [entry (assoc doc "id" (str (java.util.UUID/randomUUID)))] (if (empty? (get entry "foo")) (assoc entry "foo" 0)) (if (empty? (get entry "bar")) (assoc
(defn create-entry [doc]
(let [entry (assoc doc "id" (str (java.util.UUID/randomUUID)))]
(if (empty? (get entry "foo")) (assoc entry "foo" 0))
(if (empty? (get entry "bar")) (assoc entry "bar" 0))))
Carcigenicate评论后更新:
(defn entry [doc]
(as-> (assoc doc "id" (str (java.util.UUID/randomUUID))) e
(if (empty? (get e "foo")) (assoc e "foo" 0) e)
(if (empty? (get e "bar")) (assoc e "bar" 0) e)))
(defn create-entry [doc]
(prn (entry doc)))
你需要开始思考更多的功能。请注意,您使用的所有结构都是不可变的;他们自己永远不会改变。您的最后一行复制了
条目
,但您从未对其进行任何操作;它刚刚被扔掉了。有几种处理这种情况的方法,您需要通过几个步骤转换结构:
- 只需使用
:让
注意最后一行如何使用(let [entry (assoc doc "id" (str (java.util.UUID/randomUUID))) def-foo (if (empty? (get entry "foo")) (assoc entry "foo" 0) entry)] (if (empty? (get def-foo "bar")) (assoc def-foo "bar" 0) def-foo)))
副本,而不是原始def foo
条目
- 使用线程宏:
; Create a new binding, e, that will hold the result of the previous form (as-> (assoc doc "id" (str (java.util.UUID/randomUUID))) e (if (empty? (get e "foo")) (assoc e "foo" 0) e) (if (empty? (get e "bar")) (assoc e "bar" 0) e))
(-> (assoc doc "id" (str (java.util.UUID/randomUUID))) (update "foo" #(if (empty? %) 0 %)) (update "bar" #(if (empty? %) 0 %)))
将替换为前面的任何形式e
注意,如果你发现自己在同一个对象上使用了<代码>获取<代码> >代码> AsSOC/<代码>,你可能需要考虑使用<代码> Update < /Cord>,这大大简化了一切,特别是当与<代码> -> /Cord>线程宏:
配对时 ; Create a new binding, e, that will hold the result of the previous form
(as-> (assoc doc "id" (str (java.util.UUID/randomUUID))) e
(if (empty? (get e "foo")) (assoc e "foo" 0) e)
(if (empty? (get e "bar")) (assoc e "bar" 0) e))
(-> (assoc doc "id" (str (java.util.UUID/randomUUID)))
(update "foo" #(if (empty? %) 0 %))
(update "bar" #(if (empty? %) 0 %)))
我不得不对您的意图做一些假设,因为您的代码有一个错误,我在提交答案之前没有注意到这个错误。在原始代码中,当条件为false时,
if
s不会计算为任何值。我假设你只是不想改变任何错误的东西 你需要开始思考更实用的问题。请注意,您使用的所有结构都是不可变的;他们自己永远不会改变。您的最后一行复制了条目
,但您从未对其进行任何操作;它刚刚被扔掉了。有几种处理这种情况的方法,您需要通过几个步骤转换结构:
- 只需使用
:让
注意最后一行如何使用(let [entry (assoc doc "id" (str (java.util.UUID/randomUUID))) def-foo (if (empty? (get entry "foo")) (assoc entry "foo" 0) entry)] (if (empty? (get def-foo "bar")) (assoc def-foo "bar" 0) def-foo)))
副本,而不是原始def foo
条目
- 使用线程宏:
; Create a new binding, e, that will hold the result of the previous form (as-> (assoc doc "id" (str (java.util.UUID/randomUUID))) e (if (empty? (get e "foo")) (assoc e "foo" 0) e) (if (empty? (get e "bar")) (assoc e "bar" 0) e))
(-> (assoc doc "id" (str (java.util.UUID/randomUUID))) (update "foo" #(if (empty? %) 0 %)) (update "bar" #(if (empty? %) 0 %)))
将替换为前面的任何形式e
注意,如果你发现自己在同一个对象上使用了<代码>获取<代码> >代码> AsSOC/<代码>,你可能需要考虑使用<代码> Update < /Cord>,这大大简化了一切,特别是当与<代码> -> /Cord>线程宏:
配对时 ; Create a new binding, e, that will hold the result of the previous form
(as-> (assoc doc "id" (str (java.util.UUID/randomUUID))) e
(if (empty? (get e "foo")) (assoc e "foo" 0) e)
(if (empty? (get e "bar")) (assoc e "bar" 0) e))
(-> (assoc doc "id" (str (java.util.UUID/randomUUID)))
(update "foo" #(if (empty? %) 0 %))
(update "bar" #(if (empty? %) 0 %)))
我不得不对您的意图做一些假设,因为您的代码有一个错误,我在提交答案之前没有注意到这个错误。在原始代码中,当条件为false时,
if
s不会计算为任何值。我假设你只是不想改变任何错误的东西 为了补充Carcigenicate的回答,另一个建议是:
我会在默认地图上使用merge
或assoc
:
(merge {:default-1 123 :default-2 234} {:default-1 "foo"})
=> {:default-1 "foo", :default-2 234}
请注意,merge
的参数顺序很重要,即最右边的映射优先于最左边的映射。默认贴图值只有在未被其他贴图覆盖时才会“保留”
在本例中使用
assoc
具有相同的效果,我更喜欢该版本。为了补充Carcigenicate的答案,另一个建议是:
我会在默认地图上使用merge
或assoc
:
(merge {:default-1 123 :default-2 234} {:default-1 "foo"})
=> {:default-1 "foo", :default-2 234}
请注意,merge
的参数顺序很重要,即最右边的映射优先于最左边的映射。默认贴图值只有在未被其他贴图覆盖时才会“保留”
在本例中使用
assoc
具有相同的效果,我更喜欢该版本。感谢您提供的详细答案。你可能知道我对Clojure很陌生。我尝试使用threading宏跟踪您的答案,并用代码更改更新了帖子。但是,我不确定我是否正确解释了您的答案,因为我仍然无法打印foo或bar的默认值。@Freid001您需要调用entry
,方法是将其括在括号中:(prn(entry doc))
。请记住,符号必须是要调用的表单中的第一个元素。你所有的代码都在打印关于函数本身的信息,因为你从未调用过它。谢谢,我可以看到默认值。我只是用prn
来记录控制台的响应。正如我之前所说的,我对Clojure非常陌生。您是否可以推荐一些文档来帮助我更好地理解线程宏概念?@Freid001 Np。而且Clojure的文档非常优秀。如果我是你的话,我会开始回复,然后和他们混在一起。不过还是从->
开始吧,因为这是最简单的。阅读文档,然后播放。你会明白的。谢谢你详细的回答。你可能知道我对Clojure很陌生。我尝试使用threading宏跟踪您的答案,并用代码更改更新了帖子。但是,我不确定我是否正确解释了您的答案,因为我仍然无法打印foo或bar的默认值。@Freid001您需要调用entry
,方法是将其括在括号中:(prn(entry doc))
。请记住,符号必须是要调用的表单中的第一个元素。你所有的代码都在打印关于函数本身的信息,因为你从未调用过它。谢谢,我可以看到默认值。我只是用prn
来记录控制台的响应。正如我之前所说的,我对Clojure非常陌生。您是否可以推荐一些文档来帮助我更好地理解线程宏概念?@Freid001 Np。而且Clojure的文档非常优秀。如果我是你的话,我会开始回复,然后和他们混在一起。不过还是从->
开始吧,因为这是最简单的。阅读文档,然后播放。你会明白的。