Map “的惯用方式”;更新「;Clojure地图中的给定密钥?
假设我们有一张类似以下内容的地图:Map “的惯用方式”;更新「;Clojure地图中的给定密钥?,map,clojure,merge,Map,Clojure,Merge,假设我们有一张类似以下内容的地图: (def m {:a {:foo "bar"}}) >>> d = {'a': {'foo': 'bar'}} >>> d['a'].update({'baz': 'qux'}) >>> d {'a': {'foo': 'bar', 'baz': 'qux'}} 现在,我们想用一些新值更新m中的key:a: (def vs {:baz "qux"}) 如果这是Python,我们可以执行以下操作: (d
(def m {:a {:foo "bar"}})
>>> d = {'a': {'foo': 'bar'}}
>>> d['a'].update({'baz': 'qux'})
>>> d
{'a': {'foo': 'bar', 'baz': 'qux'}}
现在,我们想用一些新值更新m中的key:a:
(def vs {:baz "qux"})
如果这是Python,我们可以执行以下操作:
(def m {:a {:foo "bar"}})
>>> d = {'a': {'foo': 'bar'}}
>>> d['a'].update({'baz': 'qux'})
>>> d
{'a': {'foo': 'bar', 'baz': 'qux'}}
我发现最简单的Clojure等价物是定义如下函数:
(defn update-key
"
Updates a given key `k` over a map `m` with a map of values `vs`.
"
[k m vs]
(assoc m k (merge (k m) vs)))
然后调用如下所示:
(update-key :a m vs)
; => {:a {:foo "bar" :baz "qux"}}
因此,我的问题是:实现与Python dicts提供的
update()
方法相同功能的最惯用和正确的方法是什么?我想您正在寻找:
与此类似,可能也值得一看。这实际上可能更接近您的Python示例:
(def m {:a {:foo "bar"}})
(def vs {:baz "qux"})
(update-in m [:a] merge vs)
; => {:a {:foo "bar", :baz "qux"}}
更新: 即使键是一个变量值(不是编译时常数),您仍然可以通过将变量放入向量中来使用
updatein
和assoc in
:
(def m {:a {:foo "bar"}})
(def k' :baz)
(def v' "qux")
(assoc-in m [:a k'] v')
; => {:a {:foo "bar", :baz "qux"}}
还可以通过编程方式构建关键点向量:
(def m {:a {:foo "bar"}})
(def k' :baz)
(def v' "qux")
(let [ks (conj [:a] k')]
(assoc-in m ks v'))
; => {:a {:foo "bar", :baz "qux"}}
啊,太好了,
updatein
应该完全符合我的要求(assoc in
会更好,但我不知道vs
中的关键字名称)。出于某种原因,我没有发现这些文档特别说明:我在中读到了assoc和updatein
,但不知道如何合并到正确的键中。谢谢@maxcountryman-静态地不知道键/值不是问题。有关使用非静态键的示例,请参见我的更新。感谢更新。对于我正在做的事情来说,与
中的更新相比,这可能有点麻烦。如果我必须在
中使用assoc来分隔键和值,那么代码将不如在
中使用update简洁。但很高兴看到它可以做到!