cloj in clojure无法开始工作

时间:2015-01-18 13:42:50

标签: clojure

我有这个功能:

(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不是一个正确的名称,我同意。

3 个答案:

答案 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)

noisesmith's answer

之后

您对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}}一次短路解构。