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

标签 clojure hashmap

在 Clojure 中,如何找到可能位于嵌套映射结构深处的键的值?例如:

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

(find-nested m :f)

=> "f"

最佳答案

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

此外,找到所有匹配项成为替换 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]

请注意,使用 nil 映射值可能需要一些特殊处理。

更新:如果你看上面的代码,你可以看到 k实际上可以是一个提供更多可能性的函数:
  • 查找字符串键:
    (find-nested m #(get % "k"))
    
  • 查找多个键:
    (find-nested m #(some % [:a :b]))
    
  • 在整数映射中只找到正值:
    (find-nested m #(when (some-> % :k pos?) (:k %)))
    
  • 关于clojure - 在嵌套映射中查找特定键的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28091305/

    相关文章:

    oop - 在 Clojure 中扩展类的问题 : ClassFormatError: Duplicate field name&signature

    java - HashMap 在第 12 个索引中插入第一条记录

    emacs - 在 Emacs 中为 Clojure 设置 SLIME 和 Inferior-Lisp

    clojure - core.async go block 是否自行停放,或者是否存在 'scheduler' ?

    clojure - 为什么更喜欢 seq 而不是非空作为谓词?

    java - 我将如何使用 java.util.Collections 来模拟 SQL INNER JOIN 操作?

    java - 为什么下面的程序中 HashMap 类的 containsValue 方法返回 False?

    存储在 HashMap 中的 Java 泛型 Pair<String, String> 未正确检索键-> 值

    Java - 自定义 HashMap /表的一些要点

    clojure - eclipse 下的黑色和莱因