【问题标题】:Mapping over a vector performing side-effects映射执行副作用的向量
【发布时间】:2012-06-01 21:39:02
【问题描述】:

我正在尝试在 Clojure 中迭代“线条”向量。本质上,它看起来像:

[{:start {:x 1 :y 3 :z 4}, :end {:x 3 :y 7 :z 0}}, ...]

我想应用一个函数,将这些“行”中的每一个打印到一个新行上,ala:

(map #(println %) vector-of-lines)

但这似乎并没有调用该函数。我不应该在这种情况下使用“地图”功能吗?

【问题讨论】:

  • hashmap 位是红鲱鱼,所以我从标题中删除了它。

标签: clojure


【解决方案1】:
(dorun (map println vector-of-lines))

dorun 强制评估惰性序列,但也会丢弃序列中每个项目的单独结果。这非常适合纯粹用于副作用的序列,这正是您想要的。

【讨论】:

  • 问题是它没有打印任何行。我只是在向量中包含了一个示例,但它实际上的大小为 10。但是,使用 apply 仍然不会调用匿名函数。
  • println 输出应该发送到您环境中任何可能的控制台。
  • 问题不包括你提到的dorun。谢谢!
【解决方案2】:

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))

【讨论】:

  • +1 关于不将 println 包装在函数中,因为它已经是一个函数。
  • println 只是一个例子。 :D
【解决方案3】:

为了补充贾斯汀的答案,doseq 是一个宏,因此带有宏的所有限制。

我会编写一个内部使用doseqforeach 函数。

user=> (defn foreach [f xs] (doseq [x xs] (f x)))
#'user/foreach

user=> (foreach println [11 690 3 45])
11
690
3
45
nil

【讨论】:

    【解决方案4】:

    从 Clojure 1.7 开始,run! 可以满足您的需求。此方法的命名可能与dorunmap 的解决方法有关。在这种情况下使用map 时要小心。假设您在传入的函数中再次调用map。这也需要遍历序列。因此,您需要使用两次dorun

    【讨论】:

      猜你喜欢
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 2018-07-17
      • 1970-01-01
      • 2012-08-29
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多