Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering unnecessary keys in huge clojure map

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

like image 510
Tobias S Avatar asked Nov 29 '22 06:11

Tobias S


2 Answers

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)
like image 29
erdos Avatar answered Dec 04 '22 09:12

erdos


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

like image 175
leetwinski Avatar answered Dec 04 '22 10:12

leetwinski