Clojure填充地图使用进入



>我需要填充地图{:v '[], :f '[]),其中 v-array 包含以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应为返回结果图(

我可以像这样重复您的错误消息:

(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 []}

最新更新