I have a map that looks like this:
{\a [\h]
\h [\w \w]
\i [\w \h \t]
\p [\t \u \h \a]
\s [\t \a \t \t \i \w \h]
\t [\a]
\u [\t \t \s]
\w []}
I want to remove e.g. \w from both keys and values. i.e. leaving this
{\a [\h]
\h []
\i [\h \t]
\p [\t \u \h \a]
\s [\t \a \t \t \i \h]
\t [\a]
\u [\t \t \s]}
Notice, the \w key has gone and \w has gone from all the values!
Right now I have this, which works, but I'm sure there must be a better, more Clojurey way!
(defn remove-last [last cmap]
(reduce-kv (fn [acc k v]
(if (empty? v)
acc
(into acc {k (vec (filter #(not= % last) v))}))) {} cmap))
The key to remove will always be an empty vector.
How can I do this better?
I find your solution quite idiomatic. The requirement is unusual enough, that I immediately think reduce
. Your call to empty?
is not according to your spec, though. You'd have to test for the key k
being =
to last
.
Also, I wouldn't use the name last
here. It clashes with a name that is already present.
A very similar alternative would be
(defn remove-all-of [it m]
(reduce
(fn [acc [k v]]
(if (not= it k)
(assoc acc
k
(into (empty v)
(filter #(not= it %) v)))
acc))
{}
m))
This also allows you to have some other seqable thing than vectors as values by using (empty v)
.