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)
此外,找到所有匹配成为替换some为keep:
(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实际上可以是一个提供更多可能性的函数:
找到一个字符串键:
(find-nested m #(get % "k"))
Run Code Online (Sandbox Code Playgroud)找到多个键:
(find-nested m #(some % [:a :b]))
Run Code Online (Sandbox Code Playgroud)在整数映射中只找到正值:
(find-nested m #(when (some-> % :k pos?) (:k %)))
Run Code Online (Sandbox Code Playgroud)如果您知道嵌套路径,则使用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.