Sum*_*tch 4 dictionary key clojure
这是我的问题:我想要一个helpme带有地图:r并:g用空向量替换的函数,当且仅当这些键存在时.例如:
输入:
(helpme {:a "1" :r ["1" "2" "3"] :g ["4" "5"]})
Run Code Online (Sandbox Code Playgroud)
输出:
{:a "1" :r [] :g []}
Run Code Online (Sandbox Code Playgroud)
输入:
(helpme {:a "1" :r ["1" "2" "3"]})
Run Code Online (Sandbox Code Playgroud)
输出:
{:a "1" :r []}
Run Code Online (Sandbox Code Playgroud)
我可以定义一个功能"helpme"来做到这一点,但它过于复杂,我觉得必须有一个更容易(更惯用)的方式......
这是我完成的过于复杂的方式,如下所述:
(defn c [new-doc k] (if (contains? new-doc k) (assoc new-doc k []) new-doc))
(defn helpme [new-doc] (c (c new-doc :r) :g))
Run Code Online (Sandbox Code Playgroud)
(defn helpme [m]
(into m (for [[k _] (select-keys m [:r :g])]
[k []])))
Run Code Online (Sandbox Code Playgroud)
简短,只需要在一个地方进行编辑,当设置的项目数量[]发生变化时.
在我搜索仅在密钥确实存在的情况下才更新地图的 update-in 版本时,Google 坚持我可以在这里找到我的答案。对于其他寻求相同事物的人,我创建了以下辅助函数:
(defn contains-in?
[m ks]
(not= ::absent (get-in m ks ::absent)))
(defn update-if-contains
[m ks f & args]
(if (contains-in? m ks)
(apply (partial update-in m ks f) args)
m))
Run Code Online (Sandbox Code Playgroud)
这样你就可以:
> (def my-data {:a {:aa "aaa"}})
> (update-if-contains my-data [:a :aa] clojure.string/upper-case)
{:a {:aa "AAA"}}
> (update-if-contains my-data [:a :aa] clojure.string/split #" ")
{:a {:aa ["a" "aa"]}}
> (update-if-contains my-data [:a :b] clojure.string/upper-case)
{:a {:aa "aaa"}} ; no change because [:a :b] didn't exist in the map
Run Code Online (Sandbox Code Playgroud)