在嵌套映射中查找特定键的值

9 clojure

在Clojure中,如何找到嵌套地图结构中可能很深的键的值?例如:

(def m {:a {:b "b"
            :c "c"
            :d {:e "e"
                :f "f"}}})

(find-nested m :f)

=> "f"
Run Code Online (Sandbox Code Playgroud)

xsc*_*xsc 17

Clojure提供tree-seq了对任何值进行深度优先遍历的功能.这将简化查找嵌套密钥所需的逻辑:

(defn find-nested
  [m k]
  (->> (tree-seq map? vals m)
       (filter map?)
       (some k)))

(find-nested {:a {:b {:c 1}, :d 2}} :c)
;; => 1
Run Code Online (Sandbox Code Playgroud)

此外,找到所有匹配成为替换somekeep:

(defn find-all-nested
  [m k]
  (->> (tree-seq map? vals m)
       (filter map?)
       (keep k)))

(find-all-nested {:a {:b {:c 1}, :c 2}} :c)
;; => [2 1]
Run Code Online (Sandbox Code Playgroud)

请注意,带有nil值的地图可能需要一些特殊处理.


更新:如果你看一下上面的代码,你会发现它k实际上可以是一个提供更多可能性的函数:


Pau*_*den 9

如果您知道嵌套路径,则使用get-in.

=> (get-in m [:a :d :f])
=> "f"
Run Code Online (Sandbox Code Playgroud)

详情请见:https://clojuredocs.org/clojure.core/get-in

如果您不知道嵌套结构中的路径,则可以编写一个函数,该函数通过嵌套映射进行递归,查找相关的特定键,并在找到第一个键时返回其值,或者返回以下值的所有值:f in一个seq.