事實證明,司徒雷登哈洛韋發表a gist,可能是一些使用的(它使用的協議,這使得它擴展爲好):
(ns user)
(def app
"Intenal Helper"
(fnil conj []))
(defprotocol PathSeq
(path-seq* [form path] "Helper for path-seq"))
(extend-protocol PathSeq
java.util.List
(path-seq*
[form path]
(->> (map-indexed
(fn [idx item]
(path-seq* item (app path idx)))
form)
(mapcat identity)))
java.util.Map
(path-seq*
[form path]
(->> (map
(fn [[k v]]
(path-seq* v (app path k)))
form)
(mapcat identity)))
java.util.Set
(path-seq*
[form path]
(->> (map
(fn [v]
(path-seq* v (app path v)))
form)
(mapcat identity)))
java.lang.Object
(path-seq* [form path] [[form path]])
nil
(path-seq* [_ path] [[nil path]]))
(defn path-seq
"Returns a sequence of paths into a form, and the elements found at
those paths. Each item in the sequence is a map with :path
and :form keys. Paths are built based on collection type: lists
by position, maps by key, and sets by value, e.g.
(path-seq [:a [:b :c] {:d :e} #{:f}])
({:path [0], :form :a}
{:path [1 0], :form :b}
{:path [1 1], :form :c}
{:path [2 :d], :form :e}
{:path [3 :f], :form :f})
"
[form]
(map
#(let [[form path] %]
{:path path :form form})
(path-seq* form nil)))
(comment
(path-seq [:a [:b :c] {:d :e} #{:f}])
;; finding nils hiding in data structures:
(->> (path-seq [:a [:b nil] {:d :e} #{:f}])
(filter (comp nil? :form)))
;; finding a nil hiding in a Datomic transaction
(->> (path-seq {:db/id 100
:friends [{:firstName "John"}
{:firstName nil}]})
(filter (comp nil? :form)))
)
注意:在我的情況下,我也可以使用Specter
,所以如果您正在閱讀本文,您可能也想查看它。
來源
2016-01-27 08:47:48
nha
在您的例子,不應該將數據是'{[:一個:K1] 1,[:一個:K2] 2,[:B 0,] 1,[ :b 1] 2,[:b 2] 3}'? – nha
糟糕! 有中到索引seqs錯誤, 應該是: (圖矢量(範圍)COLL) 代替: (地圖矢量科爾(範圍)) 我會更新我的答案:) – kimsnj
謝謝 !我接受了你的答案,但仍然希望有一個不需要枚舉路徑的解決方案(我的用例是需要進行一些轉換的數據庫遷移)。 – nha