我正在尝试遍历 Clojure 中的“线条”向量。本质上,它看起来像:
[{:start {:x 1 :y 3 :z 4}, :end {:x 3 :y 7 :z 0}}, ...]
我想应用一个将这些“行”中的每一个打印到新行上的函数,ala:
(map #(println %) vector-of-lines)
但这似乎没有调用该函数。在这种情况下我不应该使用“地图”功能吗?
我正在尝试遍历 Clojure 中的“线条”向量。本质上,它看起来像:
[{:start {:x 1 :y 3 :z 4}, :end {:x 3 :y 7 :z 0}}, ...]
我想应用一个将这些“行”中的每一个打印到新行上的函数,ala:
(map #(println %) vector-of-lines)
但这似乎没有调用该函数。在这种情况下我不应该使用“地图”功能吗?
(dorun (map println vector-of-lines))
dorun
强制对惰性序列进行评估,但也会丢弃序列中每个项目的单独结果。这非常适合纯粹用于副作用的序列,这正是您想要的。
map
很懒惰,除非你要求,否则不会实现结果。如果要对序列中的每个元素执行副作用,并且不关心返回值,请使用doseq
:
;; returns nil, prints each line
(doseq [line vector-of-lines]
(println line))
如果您确实关心返回值,请使用(doall)
:
;; returns a sequence of nils, prints each line
(doall (map println vector-of-lines))
添加到贾斯汀的答案中,doseq
是一个宏,因此带有宏的所有限制。
我会编写一个foreach
内部使用的函数doseq
。
user=> (defn foreach [f xs] (doseq [x xs] (f x)))
#'user/foreach
user=> (foreach println [11 690 3 45])
11
690
3
45
nil
从 Clojure 1.7 开始,就有run!
了你想要的。此方法的命名可能与使用dorun
和的解决方法有关map
。map
在这种情况下使用时要小心。假设您map
在传入的函数内部再次调用。这也需要遍历序列。因此,您将需要使用dorun
两次。