I got a really big ass nested map in Clojure and I am searching for the most idiomatic way to kick out keys, which should not provided to the frontend (yes, this clojure service is running in the backend).
The datastructure looks like:
(def data
{:a 1
:b 2
:c 3
:d [{:e 5}
{:f 6
:g {
:h 8
:i 9
:j 10}
:l [{
:m 11
:n 12
:p {:q 13
:r 14
:s 15
}}
{:m 16
:n 17
:p {:q 18
:r 19
:s 20
}}]}]})
As you can see, I got a map with keys, whereby some keys got lists with maps, which have some lists again...so I know -> not pretty.
BUT...is there some way of describing the data I want to get so that every keys I do not want, get filtered out?
Thx
If you want to filter for the top-level keys only you can use select-keys
If you want to remove deeply nested keys you can use specter. For example to remove all values under :h
under :g
under every items in the vector under :d
just write:
user> (setval [:d ALL :g :h] NONE data)
yet another way, without using any external libs, employing clojure.walk
:
(defn remove-deep [key-set data]
(clojure.walk/prewalk (fn [node] (if (map? node)
(apply dissoc node key-set)
node))
data))
user> (remove-deep [:i :l] data)
;;=> {:a 1, :b 2, :c 3, :d [{:e 5} {:f 6, :g {:h 8, :j 10}}]}
user> (remove-deep [:f :p] data)
;;=> {:a 1, :b 2, :c 3, :d [{:e 5} {:g {:h 8, :i 9, :j 10}, :l [{:m 11, :n 12} {:m 16, :n 17}]}]}
The pre/postwalk is there for the exact use case you have: walk down the heterogenous collections, transforming values if necessary
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With