我需要将json转换为另一种格式,所以我使用instaparse将json转换为向量列表。
原始json:
[
{
"k1": "v1",
"k2": {
"k21": "v21",
"k22": "v22"
}
},
{
"k4": "v4",
"k5": "v5",
"k6": "v6"
}
]转换为clojure向量列表:
[:JSON
[:ARRAY
[:OBJECT
[:KEY_VALUE_PAIR [:STRING "\"k1\""] [:STRING "\"v1\""]]
[:KEY_VALUE_PAIR
[:STRING "\"k2\""]
[:OBJECT
[:KEY_VALUE_PAIR [:STRING "\"k21\""] [:STRING "\"v21\""]]
[:KEY_VALUE_PAIR [:STRING "\"k22\""] [:STRING "\"v22\""]]]]]
[:OBJECT
[:KEY_VALUE_PAIR [:STRING "\"k4\""] [:STRING "\"v4\""]]
[:KEY_VALUE_PAIR [:STRING "\"k5\""] [:STRING "\"v5\""]]
[:KEY_VALUE_PAIR [:STRING "\"k6\""] [:STRING "\"v6\""]]]]]可视化此链接中的树:visualizing tree
我想要这样的格式:
[
{
k1: "k1",
k2: {
k21: "k2.k21",
k22: "k2.k22"
}
},
{
k4: "k4",
k5: "k5",
k6: "k6"
}
]那么,如何在Clojure中遍历多分支树并收集数据呢?我发现它很少使用tree-seq和walk函数,所以我试着写代码:
(ns clojure.examples.hello
(:gen-class))
(def json-tree [:JSON [:ARRAY [:OBJECT [:KEY_VALUE_PAIR [:STRING "\"k1\""] [:STRING "\"v1\""]] [:KEY_VALUE_PAIR [:STRING "\"k2\""] [:OBJECT [:KEY_VALUE_PAIR [:STRING "\"k21\""] [:STRING "\"v21\""]] [:KEY_VALUE_PAIR [:STRING "\"k22\""] [:STRING "\"v22\""]]]]] [:OBJECT [:KEY_VALUE_PAIR [:STRING "\"k4\""] [:STRING "\"v4\""]] [:KEY_VALUE_PAIR [:STRING "\"k5\""] [:STRING "\"v5\""]] [:KEY_VALUE_PAIR [:STRING "\"k6\""] [:STRING "\"v6\""]]]]])
(defn transform-key [x]
(-> x
(clojure.string/replace "\"" "")
(clojure.string/upper-case)))
(defn transform-value [x]
(if (= x "") x (str x ".")))
(defn bf3 "return elements in tree, breath-first"
[[el & children :as tree] path] ;; a tree is a seq of one element,
;; followed by left and right child trees
(if (nil? el)
(do)
(if (= el :JSON)
(do (print (get (vec children) 0))
(bf3 (get (vec children) 0) path))
(if (= el :ARRAY)
(let [[first & rest-list] (get (vec children) 0)
rest (vec rest-list)]
(do (print "[") (bf3 first path) (bf3 rest path) (print "], ")))
(if (= el :OBJECT)
(let [[_ [_ key] & rest-list] (get (vec children) 0)
[rest] (vec rest-list)]
(do (print "{")
(print (str (transform-key key) ": "))
(print (str "rest====>" rest))
(bf3 rest (transform-key key))
(print "}, ")))
(if (= el :KEY_VALUE_PAIR)
(do (print (str (transform-key (get first 1)) ": "))
(bf3 rest (str (transform-value path) (transform-key (get first 1)))))
(print (str "\"" path "\", "))))))))
(bf3 json-tree "")但这段代码似乎只能遍历一个分支,其余分支则不能遍历。
发布于 2021-06-05 02:39:12
您绝对应该考虑使用clojure.walk
https://stackoverflow.com/questions/67656049
复制相似问题