Find Value of Specific Key in Nested Map

后端 未结 4 696
一向
一向 2021-02-08 09:40

In Clojure, how can I find the value of a key that may be deep in a nested map structure? For example:

(def m {:a {:b \"b\"
            :c \"c\"
            :d {         


        
4条回答
  •  臣服心动
    2021-02-08 10:21

    Here is a version that will find the key without knowing the path to it. If there are multiple matching keys, only one will be returned:

    (defn find-key [m k]
      (loop [m' m]
        (when (seq m')
          (if-let [v (get m' k)]
            v
            (recur (reduce merge
                           (map (fn [[_ v]]
                                  (when (map? v) v))
                                m')))))))
    

    If you require all values you can use:

    (defn merge-map-vals [m]
      (reduce (partial merge-with vector)
              (map (fn [[_ v]]
                     (when (map? v) v))
                   m)))
    
    (defn find-key [m k]
      (flatten
       (nfirst
        (drop-while first
                    (iterate (fn [[m' acc]]
                               (if (seq m')
                                 (if-let [v (get m' k)]
                                   [(merge-map-vals m') (conj acc v)]
                                   [(merge-map-vals m') acc])
                                 [nil acc]))
                             [m []])))))
    

提交回复
热议问题