Clojure apply vs map
我有一个从函数返回的序列(foundApps),我想将一个函数映射到它的所有元素。由于某些原因,
1 2 3 4 | (apply println foundApps) (map println rest foundApps) (map (fn [app] (println app)) foundApps) (println (str"Found" (count foundApps)" apps to delete")))) |
打印:
1 2 | {:description another descr, :title apptwo, :owner jim, :appstoreid 1235, :kind App, :key #<Key App(2)>} {:description another descr, :title apptwo, :owner jim, :appstoreid 1235, :kind App, :key #<Key App(4)>} Found 2 apps to delete for id 1235 |
所以
您很有可能被
中的
1 | (dorun (map println foundApps)) |
此外,由于您仅出于副作用而这样做,因此使用
1 2 | (doseq [fa foundApps] (println fa)) |
请注意,
还请注意,
我对此帖子缺少一个简单的解释。让我们想象一个抽象函数
1 | (apply F [1 2 3 4 5]) |
翻译为
1 | (F 1 2 3 4 5) |
这意味着
而
1 | (map F [1 2 3 4 5]) |
翻译为
1 | [(F 1) (F 2) (F 3) (F 4) (F 5)] |
这意味着
关于类型有一些细微差别,因为
稍作解释可能会有所帮助。通常,您可以使用apply将元素序列喷入函数的一组参数中。因此,将函数应用于某些参数仅意味着在单个函数调用中将它们作为参数传递给函数。
map函数将执行您想要的操作,通过将输入的每个元素插入函数然后创建输出来创建新的seq。但是它会延迟执行,因此仅当您实际遍历列表时才计算值。要强制执行此操作,可以使用(doall my-seq)函数,但是大多数时候您不需要这样做。
如果由于操作有副作用(例如打印或保存到数据库等)而需要立即执行操作,则通常使用doseq。
因此要将" foo"附加到所有应用程序(假设它们是字符串):
(map (fn [app] (str app"foo")) found-apps)
或将shorhand用于匿名功能:
(map #(str %"foo") found-apps)
执行以下操作但可以立即打印:
(doall (map #(println %) found-apps))
(doseq [app found-apps] (println app))