Search code examples
clojure

Clojure: a function that search for a val in a nested hashmap and returns the sequence of keys in which the val is contained


Say we have a collection containing a nested data structure:

(def coll
  {:a "aa"
   :b {:d "dd"
       :e {:f {:h "hh"
               :i "ii"}
           :g "gg"}}
   :c "cc"})

I would like to create a function that search for a val anywhere in the nested structure and returns the sequence of keys in which the val is contained

(search-parents "gg" coll) ; or (search-parents coll "gg")
;> [:b :e :g]

Thanks!


Solution

  • As far as I can tell, there's no built-in function that does this. It seems like you're essentially looking for an inverse of clojure.core/get-in. I thinking clojure.walk might be useful here, but I don't think this is a very good fit.

    However, it's pretty straightforward to code up a recursive function to do the search and only return matching keys:

    (defn find-in [coll x]
      (some
        (fn [[k v]]
          (cond (= v x) [k]
                (map? v) (if-let [r (find-in v x)]
                           (into [k] r))))
        coll))