我需要填充地图{:v '[], :f '[])
,其中v数组包含以v
开头的行中的数据。我该怎么办?
文件示例:
# comment
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)] }
我的尝试:
(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- create-model
[lines]
(doseq [data lines]
(into {:v '[] :f '[]}
(->>
(let [[type & remaining] data]
(case type
"v" [:v remaining]
"f" [:f remaining]))))))
(defn parse
[filename]
(->>
(lines-with-data filename)
(map #(str/split % #"\s+"))
(create-model)))
例外:
user=> (p/parse "test.obj")
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)
({parse
应该是返回结果图)
答案 0 :(得分:2)
我可以像这样重复您的错误消息:
(into {:v '[] :f '[]} [:v [:a :b]])
我可以按照我的意愿执行程序,如下所示:
(assoc {:v '[] :f '[]} :v [:a :b])
;; => {:v [:a :b], :f []}
在这里,我只是使用[:a :b]
而不是remaining
。在您的情况下,remaining
是一个数字序列,但这并不重要。
对于错误消息,这是一个非常糟糕的消息,应该在以后的Clojure版本中消失。通常是因为您为map
提供了一个关键字,而不是可以调用seq
的东西。这里的消息来自比我理解的深的地方。
我认为您想要的另一种可行的构造是:
(into {:v '[] :f '[]} [[:v [:a :b]]])
into
地图需要一系列地图输入。您忘记包装要放入地图的单个地图条目。我的REPL结果:
{:v [:a :b], :f []}