问题
I have a function that removes a key from a map:
(defn remove-key [key map]
(into {}
(remove (fn [[k v]] (#{key} k))
map)))
(remove-key :foo {:foo 1 :bar 2 :baz 3})
How do i apply this function using multiple keys?
(remove-keys [:foo :bar] {:foo 1 :bar 2 :baz 3})
I have an implementation using loop...recur. Is there a more idiomatic way of doing this in Clojure?
(defn remove-keys [keys map]
(loop [keys keys
map map]
(if (empty? keys)
map
(recur (rest keys) (remove-key (first keys) map)))))
回答1:
Your remove-key
function is covered by the standard library function dissoc
. dissoc
will remove more than one key at a time, but it wants the keys to be given directly in the argument list rather than in a list. So you can use apply
to "flatten" it out.
(apply dissoc {:foo 1, :bar 2, :baz 3} [:foo :bar])
==> {:baz 3}
回答2:
dissoc removes one or more keys from a map:
(dissoc {:foo 1 :bar 2 :baz 3} :foo :bar)
or, if you have the keys in a collection
(apply dissoc {:foo 1 :bar 2 :baz 3} [:foo :bar])
回答3:
As others said use the built-in function instead of writing your own.
However, if this was just an example and you want an answer of how to do that if there wasn't a standard dissoc, then you can use:
(reduce (fn [m k] (remove-key k m)) {:foo 1 :bar 2 :baz 3} [:foo :bar])
Obviously, if you revert the arguments to remove-key it can be written much simpler:
(reduce remove-key {:foo 1 :bar 2 :baz 3} [:foo :bar])
回答4:
I found this type of thing and others to be super annoying in clojure, so to fix it I created the library instar: https://github.com/boxed/instar .
来源:https://stackoverflow.com/questions/9717606/how-to-remove-multiple-keys-from-a-map