在 Clojure 中,如何找到可能位于嵌套映射结构深处的键的值?例如:
(def m {:a {:b "b"
:c "c"
:d {:e "e"
:f "f"}}})
(find-nested m :f)
=> "f"
Clojure 提供tree-seq http://conj.io/store/v0/org.clojure/clojure/1.6.0/clj/clojure.core/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
此外,找到所有匹配项就变成了替换的问题some
with 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]
请注意,地图与nil
值可能需要一些特殊处理。
Update:如果你看上面的代码,你会发现k
实际上可以是一个提供更多可能性的函数:
-
查找字符串键:
(find-nested m #(get % "k"))
-
查找多个键:
(find-nested m #(some % [:a :b]))
-
在整数映射中仅查找正值:
(find-nested m #(when (some-> % :k pos?) (:k %)))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)