如何从地图中删除多个键?

时间:2012-03-15 10:09:19

标签: clojure

我有一个从地图中删除密钥的功能:

(defn remove-key [key map]
  (into {}
        (remove (fn [[k v]] (#{key} k))
                map)))

(remove-key :foo {:foo 1 :bar 2 :baz 3})

如何使用多个键应用此功能?

(remove-keys [:foo :bar] {:foo 1 :bar 2 :baz 3})

我有一个使用loop ... recur的实现。在Clojure中有更惯用的方法吗?

(defn remove-keys [keys map]
  (loop [keys keys
         map map]
    (if (empty? keys)
      map
      (recur (rest keys) (remove-key (first keys) map)))))

3 个答案:

答案 0 :(得分:47)

标准库函数remove-key涵盖了您的dissoc函数。 dissoc一次会删除多个键,但它希望键直接在参数列表中而不是在列表中给出。因此,您可以使用apply来“扁平化”。

(apply dissoc {:foo 1, :bar 2, :baz 3} [:foo :bar])
==> {:baz 3}

答案 1 :(得分:44)

dissoc从地图中删除一个或多个键:

(dissoc {:foo 1 :bar 2 :baz 3} :foo :bar)

或者,如果您拥有集合中的密钥

(apply dissoc {:foo 1 :bar 2 :baz 3} [:foo :bar])

答案 2 :(得分:11)

正如其他人所说的那样使用内置函数而不是编写自己的函数。

但是,如果这只是一个例子而且如果没有标准的dissoc你想要如何做到这一点,那么你可以使用:

(reduce (fn [m k] (remove-key k m)) {:foo 1 :bar 2 :baz 3} [:foo :bar])

显然,如果你将参数恢复为remove-key,可以写得更简单:

(reduce remove-key {:foo 1 :bar 2 :baz 3} [:foo :bar])