clojure 找到任意嵌套的键
clojure find arbitrarily nested key
Clojure 中是否有一种简单的方法(可能使用 specter)来根据具有已知名称的任意嵌套键是否包含元素来过滤集合?
例如。 :
(def coll [{:res [{:a [{:thekey [
"the value I am looking for"
...
]
}
]}
{:res ...}
{:res ...}
]}])
知道 :a
可以有不同的名称,并且 :thekey
可以嵌套在其他地方。
假设我想做:
#(find-nested :thekey #{"the value I am looking for"} coll) ;; returns a vector containing the first element in coll (and maybe others)
使用拉链。
在回复中:
user> coll
[{:res [{:a [{:thekey ["the value I am looking for"]}]} {:res 1} {:res 1}]}]
user> (require '[clojure.zip :as z])
nil
user> (def cc (z/zipper coll? seq nil coll))
#'user/cc
user> (loop [x cc]
(if (= (z/node x) :thekey)
(z/node (z/next x))
(recur (z/next x))))
["the value I am looking for"]
更新:
这个版本是有缺陷的,因为它不关心 :thekey 是映射中的键,还是向量中的关键字,所以它会为 coll [[:thekey [1 2 3]]]
提供不需要的结果。这是一个更新版本:
(defn lookup-key [k coll]
(let [coll-zip (z/zipper coll? #(if (map? %) (vals %) %) nil coll)]
(loop [x coll-zip]
(when-not (z/end? x)
(if-let [v (-> x z/node k)] v (recur (z/next x)))))))
回复:
user> (lookup-key :thekey coll)
["the value I am looking for"]
user> (lookup-key :absent coll)
nil
假设我们在 coll 的向量中某处有相同的关键字:
(def coll [{:res [:thekey
{:a [{:thekey ["the value I am looking for"]}]}
{:res 1} {:res 1}]}])
#'user/coll
user> (lookup-key :thekey coll)
["the value I am looking for"]
这就是我们需要的。
Clojure 中是否有一种简单的方法(可能使用 specter)来根据具有已知名称的任意嵌套键是否包含元素来过滤集合?
例如。 :
(def coll [{:res [{:a [{:thekey [
"the value I am looking for"
...
]
}
]}
{:res ...}
{:res ...}
]}])
知道 :a
可以有不同的名称,并且 :thekey
可以嵌套在其他地方。
假设我想做:
#(find-nested :thekey #{"the value I am looking for"} coll) ;; returns a vector containing the first element in coll (and maybe others)
使用拉链。 在回复中:
user> coll
[{:res [{:a [{:thekey ["the value I am looking for"]}]} {:res 1} {:res 1}]}]
user> (require '[clojure.zip :as z])
nil
user> (def cc (z/zipper coll? seq nil coll))
#'user/cc
user> (loop [x cc]
(if (= (z/node x) :thekey)
(z/node (z/next x))
(recur (z/next x))))
["the value I am looking for"]
更新:
这个版本是有缺陷的,因为它不关心 :thekey 是映射中的键,还是向量中的关键字,所以它会为 coll [[:thekey [1 2 3]]]
提供不需要的结果。这是一个更新版本:
(defn lookup-key [k coll]
(let [coll-zip (z/zipper coll? #(if (map? %) (vals %) %) nil coll)]
(loop [x coll-zip]
(when-not (z/end? x)
(if-let [v (-> x z/node k)] v (recur (z/next x)))))))
回复:
user> (lookup-key :thekey coll)
["the value I am looking for"]
user> (lookup-key :absent coll)
nil
假设我们在 coll 的向量中某处有相同的关键字:
(def coll [{:res [:thekey
{:a [{:thekey ["the value I am looking for"]}]}
{:res 1} {:res 1}]}])
#'user/coll
user> (lookup-key :thekey coll)
["the value I am looking for"]
这就是我们需要的。