【问题标题】:How can I merge within a nested hashmap?如何在嵌套的哈希图中合并?
【发布时间】:2014-03-26 21:11:39
【问题描述】:

我有一个嵌套的 hashmap,其结构如下:

(def pathmap {:order {:genus {:species {:cat2 "data", :cat1 "data"}}}})

我需要的是一个类似 assoc-in 的函数,它允许我将新的键值对添加到最里面的嵌套映射中,而不是简单地替换已经存在的内容。例如:

(my-assoc-merge pathmap [:order :genus :species] {:cat3 "data"})
;=> {:order {:genus {:species {:cat3 "data" :cat2 "data", :cat1 "data"}}}}

我想我可以通过稍微改变 assoc-in 函数来使用 merge-with 和 union 来轻松做到这一点:

(defn my-assoc-merge
  [m [k & ks] v]
  (if ks
    (assoc m k (my-assoc-merge (get m k) ks v))
    (assoc m k (merge-with clojure.set/union (get m k '{}) v))))

不幸的是,这给了我错误“CompilerException java.lang.UnsupportedOperationException:此类型不支持计数:关键字,编译:(core.clj:34:12)”。我哪里错了?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    实际上,assoc-in 已经创建了一个新密钥,如果它不存在的话。用法如下:

    (def pathmap {:order {:genus {:species {:cat2 "data", :cat1 "data"}}}})
    
    (assoc-in pathmap [:order :genus :species :cat3] "data")
    ;=> {:order {:genus {:species {:cat2 "data", :cat3 "data", :cat1 "data"}}}}
    

    如果您希望合并新地图,请使用 update-inmerge

    (update-in pathmap [:order :genus :species] merge {:cat3 "data"})
    ;=> {:order {:genus {:species {:cat2 "data", :cat3 "data", :cat1 "data"}}}}
    

    您的my-assoc-merge 的问题在于union 可以在集合上使用。将merge-with 更改为merge 并删除union

    【讨论】:

    • 出色语言中的出色功能。
    • update-in 完全符合我的要求。也感谢您的更正。
    猜你喜欢
    • 2019-02-21
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    • 2021-11-16
    • 2021-11-28
    • 2015-11-22
    相关资源
    最近更新 更多