我有这个功能:
(defn dissoc-all [m kv]
(let [[k & ks] kv]
(dissoc m k ks)))
m
是地图,kv
是键的向量。我这样用它:
(dissoc-all {:a 1 :b 2} [:a :b])
=>{:b 2}
这不是我的预期。 ks
有:b
,但我不知道dissoc
没有使用它的原因。有人可以帮我这个吗?
修改:添加的问题是,为什么这不会触发dissoc
的第3次重载,即dissoc [map key & ks]
?
将名称从dissoc-in更改为dissoc-all,因为noisesmith已经说过,-in不是一个正确的名称,我同意。
答案 0 :(得分:3)
这不起作用,因为ks
是第一个之后kv
中所有元素的集合。因此:b
取代[:b]
而不是(defn dissoc-in [m vs]
(apply dissoc m vs))
。
相反,您可以使用apply:
dissoc-in
此外,-in
是此函数的奇怪名称,因为名称中带有{{1}}的标准函数都执行嵌套访问,并且这不使用键来执行任何嵌套访问地图。
答案 1 :(得分:2)
为什么不是这样的?
(defn dissoc-all [m ks]
(apply dissoc m ks))
(dissoc-all {:a 1 :b 2} [:a :b])
=> {}
dissoc
的第三个版本未被调用的原因是因为它不期望像[:a :b]
这样的密钥集合 - 它只需要密钥。
例如:
(dissoc {:a "a" :b "b" :c "c" :d "d"} :a :b :c)
=> {:d "d"}
答案 2 :(得分:1)
您对dissoc
的重载/元素感到困惑,这会产生这种简单的效果:
[m & ks]
"Returns a new map of the same (hashed/sorted) type,
that does not contain a mapping for any of ks. "
无密钥和一个密钥的显式arities用于提高性能。许多clojure函数是如此有条理,文档遵循组织,而不是基本的想法。
现在,
的行动(dissoc-all {:a 1 :b 2} [:a :b])
;{:b 2}
是绑定
k
至:a
ks
至[:b]
注意后者。该示例删除了:a
,但无法移除[:b]
,而不是apply
。
您可以使用ks
来破解(defn dissoc-all [m kk]
(let [[k & ks] kk]
(apply dissoc m k ks)))
(dissoc-all {:a 1 :b 2} [:a :b])
;{}
:
apply
......或者更好的是,像@noisesmith那样做,并使用{{1}}一次短路解构。