如何在Clojure的嵌套数组映射中找到键值的路径? [英] How to find the path of keys to a value in a nested array map in Clojure?
问题描述
假设我有:
(def a-map {:foo "bar" :biz {:baz "qux"}})
如何找到给定值 qux的键路径,使得
How would I find the path of keys to a given value "qux" such that
(get-in a-map <the resulting path>)
是否会返回 qux?
换句话说,一个带有a-map和 qux并返回[:biz:baz]。
In other words, a function that takes a-map and "qux" and returns [:biz :baz].
我将能够使用返回的路径,如下所示:
I would then be able to use the returned path like this:
(get-in a-map [:biz :baz])
并获得 qux。
我需要的路径比这个简单的例子要嵌套得多。
The paths I need are going to be far more nested than this simple example.
我想在html中找到已使用山胡桃解析为数组映射的html中给定值的路径。我想要执行此操作,而不必尝试在脑海中浏览数十个嵌套的键/值。我愿意接受其他策略。
I am wanting to find the path to a given value in html that has been parsed into an array map using hickory. I want to do this without having to try to mentally navigate down through dozens of nested key/values. I'm open to other strategies.
推荐答案
您可以雇用拉链为此:例如,
you can employ zipper for that: like this, for example:
user> (require '[clojure.zip :as z])
nil
user>
(loop [curr (z/zipper coll? seq nil a-map)]
(cond (z/end? curr) nil
(-> curr z/node (= "qux")) (->> curr
z/path
(filter map-entry?)
(mapv first))
:else (recur (z/next curr))))
;;=> [:biz :baz]
或相同,但更具声明性风格:
or the same, but in a more 'declarative' style:
(some->> a-map
(z/zipper coll? seq nil)
(iterate z/next)
(take-while (complement z/end?))
(filter #(= (z/node %) "qux"))
first
z/path
(filter map-entry?)
(mapv first))
更新
您还可以使用经典的递归方法:
you can also use the classic recursive approach:
(defn get-path [endpoint data]
(cond (= endpoint data) []
(map? data) (some (fn [[k v]]
(when-let [p (get-path endpoint v)]
(cons k p)))
data)))
user> (get-path "qux" a-map)
;;=> (:biz :baz)
这篇关于如何在Clojure的嵌套数组映射中找到键值的路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!