Parsing 要映射的Clojure惯用读取文件
我需要读取文件以映射{:v'[]:f'[]}。我分割每一行,若第一个元素是v,那个么我将剩余的部分添加到v数组中,对于f数组也是如此 例如:Parsing 要映射的Clojure惯用读取文件,parsing,clojure,Parsing,Clojure,我需要读取文件以映射{:v'[]:f'[]}。我分割每一行,若第一个元素是v,那个么我将剩余的部分添加到v数组中,对于f数组也是如此 例如: v 1.234 3.234 4.2345234 v 2.234 4.235235 6.2345 f 1 1 1 预期结果: {:v [("1.234" "3.234" "4.2345234"), ("2.234" "4.235235" "6.2345")] :f [("1" "1" "1")]} 我的结果是: {:v [("2.234" "4.235
v 1.234 3.234 4.2345234
v 2.234 4.235235 6.2345
f 1 1 1
预期结果:
{:v [("1.234" "3.234" "4.2345234"), ("2.234" "4.235235" "6.2345")]
:f [("1" "1" "1")]}
我的结果是:
{:v [("2.234" "4.235235" "6.2345")]
:f [("1" "1" "1")]}
问题:
如何修复错误?只有最后一行被添加到地图中
我能避免全局变量模型和副作用吗?
代码:
您似乎正在删除模型的更改状态,而不是使用两个空向量将所有行的数据附加到原始模型。您可以在读取文件时保持模型的状态,例如使用reduce:
(def model
{:v '[]
:f '[]})
(defn- file-lines
[filename]
(line-seq (io/reader filename)))
(defn- lines-with-data
[filename]
(->>
(file-lines filename)
(filter not-empty)
(filter #(not (str/starts-with? % "#")))))
(defn- to-item [data]
(let [[type & remaining] data]
(case type
"v" [:v (conj (:v model) remaining)]
"f" [:f (conj (:f model) remaining)])))
(defn- fill-model
[lines]
(into model
(for [data lines] (to-item data))))
(defn parse
[filename]
(->>
(lines-with-data filename)
(map #(str/split % #"\s+"))
(fill-model)))
(defn- add-item [m data]
(let [[type & remaining] data]
;; Updates the model `m` by appending data under the given key.
;; In the line below, `(keyword type)` will be :v or :f depending on `type`.
;; Returns the updated model.
(update m (keyword type) conj remaining)))
(defn fill-model [lines]
;; Applies `add-item` to the original model and each line of the file
(reduce add-item model lines)))