[英]In Clojure, How to read a hierarchical data structure from a text file?
我有一個文本文件,其內容如下:
section1
name=test
value
attr1=v1
attr2=v2
section2
age=20
prop
attr3=v3
我想讀取它,並將其呈現為樹數據結構(或JSON),例如:
{:section1
{:name "test"
:value {:attr1 "v1"
:attr2 "v2" }}
:section2
{:age 20
:prop {:attr3 "v3" }}
}
我如何在沒有額外lib的情況下使用核心clojure進行操作? 我發現在處理分層數據結構內很難處理中間狀態。
首先,您需要一個解析行的函數:
(defn parse-lines [s]
(->> (clojure.string/split-lines s)
(remove empty?)
(map #(re-matches #"( *)([^ =]+)(?:=(.+))?" %))
(map (fn [[_ level key value]]
[(-> (or level "")
(count)
(quot 4))
(keyword key)
value]))))
(parse-lines content)
;; =>
([0 :section1 nil]
[1 :name "test"]
[1 :value nil]
[2 :attr1 "v1"]
[2 :attr2 "v2"]
[0 :section2 nil]
[1 :age "20"]
[1 :prop nil]
[2 :attr3 "v3"])
然后,您需要一個在行上遞歸迭代並創建嵌套映射的函數:
(defn reduce-lines [lines]
(loop [[x & xs] lines
path []
prev-key nil
result {}]
(if-let [[l k v] x]
(let [indent (- (count path) l)
path (case indent
0 path
-1 (conj path prev-key)
(->> path (drop indent) vec))]
(recur xs path k (assoc-in result (conj path k) v)))
result)))
(reduce-lines (parse-lines content))
;; =>
{:section1 {:name "test", :value {:attr1 "v1", :attr2 "v2"}},
:section2 {:age "20", :prop {:attr3 "v3"}}}
請注意,沒有縮進和內容格式錯誤的斷言。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.