5

我做了:

user=> (println (for [line (range 1 5)] (str "line=" line)))

并得到:

(line=1 line=2 line=3 line=4)

但我只想line=1 line=2 line=3 line=4作为一个字符串。我该怎么做呢?

4

3 回答 3

9

你需要“申请”。

(apply println (for [line (range 1 5)] (str "line=" line)))

或者,

(println (apply str (interpose " " (map #(str "line=" %) (range 1 5)))))
于 2012-09-21T18:00:04.293 回答
3

这个如何。doseq是关于对序列进行副作用,而打印是副作用。

(doseq [line (range 1 5) 
        :let [msg (str "line=" line " ")]] 
       (print msg))
于 2012-09-22T04:46:06.403 回答
2

而不是apply,您也可以reduce像这样使用:

user> (reduce #(str %1 " line=" %2) "" (range 1 5))
=> " line=1 line=2 line=3 line=4"

reduce函数是一个函数,它接受一个函数(让我们调用 if f)、一个“起始值”,然后是一个将用作f的第二个参数的事物列表。它在起始值和列表中的第一项上懒惰地调用f ,然后在 this 返回的内容和列表中的第二项上调用f ,然后对返回的内容和列表中的第三项等调用 f,直到已经用尽了列表中的所有项目(或者更确切地说——因为它是懒惰的,如果你“要求它”它只会遍历整个列表)。

如果你不喜欢起始空间,你可以把整个东西都包起来triml(你必须先做(use 'clojure.string))。或者你可以这样做(reduce #(str %1 "line=" %2 " ") (range 1 5)),这会将空间放在最后。

我的经验是,只要apply你可以用reduce. 更重要的是,我的reduce替代方案通常总是比我的更快apply我当然不能保证这将永远是正确的,而且我还没有针对您的特定问题进行速度测试。

编辑
我做了一些粗略的计时,使用我的版本 ( reduce) 与 JohnJ 的第二个建议 ( apply),并发现它们在高达 1 时非常相似(range 1 100),但到 1 时(range 1 500)apply版本至少快 4 倍。

于 2012-09-21T23:30:53.187 回答