我做了:
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
作为字符串。我该怎么做?
答案 0 :(得分:8)
您需要'申请'。
(apply println (for [line (range 1 5)] (str "line=" line)))
可替换地,
(println (apply str (interpose " " (map #(str "line=" %) (range 1 5)))))
答案 1 :(得分:3)
这个怎么样? doseq
是关于对序列进行副作用,打印是副作用。
(doseq [line (range 1 5)
:let [msg (str "line=" line " ")]]
(print msg))
答案 2 :(得分:2)
您可以选择使用reduce
代替apply
,而不是user> (reduce #(str %1 " line=" %2) "" (range 1 5))
=> " line=1 line=2 line=3 line=4"
。
reduce
(use 'clojure.string)
函数是一个函数,它接受一个函数(如果 f 则让我们调用),一个“起始值”,然后是一个将用作第二个函数的列表 f 的论据。它懒洋洋地在起始值和列表中的第一项上调用 f ,然后在返回的内容和列表中的第二项上调用 f ,然后调用 f 关于它返回的内容以及列表中的第三项等等,直到它已经耗尽列表中的所有项目(或者更确切地说 - 因为它是懒惰的,如果你“问”它只会通过整个列表它到“)。
如果你不喜欢开始空间,你可以将整个事情包裹在triml
中(你必须先做(reduce #(str %1 "line=" %2 " ") (range 1 5))
)。或者你可以做apply
,这会把空间放在最后。
我的经验是,只要您可以使用reduce
执行某些操作,就可以使用reduce
稍微优雅地执行此操作。更重要的是,我的apply
替代方案始终通常比我的reduce
更快。 我当然不能保证这一切都是真的,而且我没有为你的特定问题做过速度测试。
修改强>
我使用我的版本(apply
)与JohnJ的第二个建议((range 1 100)
)做了一些粗略的计时,发现它们非常相似,直到(range 1 500)
,但是{{1} {},apply
版本至少快了4倍。