Reputation: 21090
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)))))
Upvotes: 37
Views: 19255
Reputation: 4427
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 .
Upvotes: 1
Reputation: 3919
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])
Upvotes: 11
Reputation: 3870
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}
Upvotes: 64