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

Sat*_*ish 31 clojure

我有一个从地图中删除键的函数:

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

(remove-key :foo {:foo 1 :bar 2 :baz 3})
Run Code Online (Sandbox Code Playgroud)

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

(remove-keys [:foo :bar] {:foo 1 :bar 2 :baz 3})
Run Code Online (Sandbox Code Playgroud)

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

(defn remove-keys [keys map]
  (loop [keys keys
         map map]
    (if (empty? keys)
      map
      (recur (rest keys) (remove-key (first keys) map)))))
Run Code Online (Sandbox Code Playgroud)

deo*_*ong 47

您的remove-key功能由标准库函数涵盖dissoc.dissoc将一次删除多个键,但它希望键直接在参数列表中而不是在列表中给出.所以你可以用它apply来"扁平化"它.

(apply dissoc {:foo 1, :bar 2, :baz 3} [:foo :bar])
==> {:baz 3}
Run Code Online (Sandbox Code Playgroud)


Jon*_*nas 44

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

(dissoc {:foo 1 :bar 2 :baz 3} :foo :bar)
Run Code Online (Sandbox Code Playgroud)

或者,如果你有一个集合中的钥匙

(apply dissoc {:foo 1 :bar 2 :baz 3} [:foo :bar])
Run Code Online (Sandbox Code Playgroud)

  • @ john2x,`apply`就是这么做的.即,`(应用f foo bar baz)`相当于python中的`f(foo bar*baz)`. (5认同)

iva*_*ant 11

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

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

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

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

(reduce remove-key {:foo 1 :bar 2 :baz 3} [:foo :bar])
Run Code Online (Sandbox Code Playgroud)