Clojure中是否有标准的“foreach”函数?

23
Clojure> (doc foreach)
Unable to resolve var: foreach in this context

Clojure> (doc map)
-------------------------
clojure.core/map
([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])

当然,我可以使用 "map" 来模拟 "foreach",但是 map 总是返回 nil,这使得下面的函数输出很难看:

(defn div618 [p1 p2]
    (let [ratio [0.,0.191,0.236,0.382,0.5,0.618,0.809,1.]
          price (fn [r] (if (<= p1 p2) (+ p1 (* (- p2 p1) r)) (- p1 (* (- p1 p2) r))))]

    (if (<= p1 p2)
        (**map** #(println (format "-------%.3f   %.2f-------" %1 (price %1))) (reverse ratio))
        (**map** #(println (format "-------%.3f   %.2f-------" %1 (price %1)))  ratio))))

真诚地!


什么是 **map**?你是不是想要将那个名称设置为粗体?此外,你知道在标记之间可以随时使用换行符,对吧? - Svante
6个回答

72

我认为doseq可能是您正在寻找的:

(doseq [i [0 1 2 3]] (println i))
然而这仍将返回nil - Clojure中的所有形式都会被评估为某个值;不存在类似于Common Lisp的(values)的等效物。

12
请在左边打勾以接受答案。此外,您可能希望点赞它。 - Svante

12

正是我所需要的。像 Julia 的 foreach 一样工作。 - Post Self

3

map函数用于对序列中的每个元素应用函数f,您的情况下应用了返回nil的print函数,因此您会得到一个中间的nil序列,然后将其丢弃。如果您想要像打印这样的副作用,可以使用doseq。

Clojure没有单一的foreach形式,例如map、reduce、filter等都是foreach形式,它们都对序列中的每个元素执行某些操作。另外,map是惰性的,您的示例只会在repl中打印,因为repl会强制懒惰的序列实现自己,如果您将其打包成jar文件,则不会执行任何操作。


3
您可以使用doseq或doall。以下是使用doall的示例。
(defn div618 [p1 p2]
    (let [ratio [0.,0.191,0.236,0.382,0.5,0.618,0.809,1.]
          price (fn [r] (if (<= p1 p2) (+ p1 (* (- p2 p1) r)) (- p1 (* (- p1 p2) r))))]
(doall (map #(println (format "-------%.3f %.2f-------" %1 (price %1))) (if (<= p1 p2) (reverse ratio) ratio)))))
您也可以将打印与函数计算分开,像这样:
(defn div618 [p1 p2]
    (let [ratio [0.,0.191,0.236,0.382,0.5,0.618,0.809,1.]
          price (fn [r] (if (<= p1 p2) (+ p1 (* (- p2 p1) r)) (- p1 (* (- p1 p2) r))))]
(map (fn [x] [x (price x)]) (if (<= p1 p2) (reverse ratio) ratio))))
(doall (map #(println (format "-------%.3f %.2f-------" (first %1) (last %1))) (div618 1 2)))

2

Clojure> (for [x (range 10)] (inc x)) (1 2 3 4 5 6 7 8 9 10) Clojure> (for [x (range 10)] (println x)) (nil nil nil nil nil nil nil nil nil nil) - z_axis

1
(defn div618 [p1 p2]
  (let [ratio [0.000 0.191 0.236 0.382 0.500 0.618 0.809 1.000]            
        price #(if (<= p1 p2)
                 (-> p2 (- p1) (* %) (+ p1))
                 (-> p1 (- p2) (* %) (- p1)))
        print-all #(doseq [item %]
                     (printf "-------%.3f   %.2f-------\n" item (price item)))]
    (if (<= p1 p2)
      (print-all (reverse ratio))
      (print-all ratio))))

注意:无逗号,使用线程优先(->)的即席从左到右的数学语法和 doseq,它本质上是Clojure的 foreach - divs1210

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接