Clojure中有标准的“foreach”功能吗?

时间:2011-09-06 02:40:34

标签: clojure

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”,但是地图总是返回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))))

此致!

6 个答案:

答案 0 :(得分:56)

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

(doseq [i [0 1 2 3]] (println i))

然而,这仍然会返回nil - Clojure中的所有表单都会评估为某个值;没有相当于Common Lisp的(values)

答案 1 :(得分:5)

从Clojure 1.7开始,您可以使用run!

user=> (run! println (range 10))

0
1
2
3
4
5
6
7
8
9
=> nil  ; returns nil

请参阅this answerHow to print each item of list on separate line clojure?

答案 2 :(得分: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)))

答案 3 :(得分:2)

map用于将函数f应用于seq的每个元素,在你的情况下你的应用print返回nil,所以你得到一个nils的中间seq然后你扔掉。当您想要打印等副作用时,请使用doseq。

Clojure没有单一的foreach表单映射,减少过滤器等。从技术上讲,这些都是foreach表单,它们都对seq中的每个元素执行某些操作。另外地图是懒惰你的例子只会在repl中打印导致repl强制懒惰seq实现它们自己说如果你把它装在一个罐子里就不会做任何事情。

答案 4 :(得分:0)

我认为你想要clojure的列表理解,请参阅:http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#List_Comprehension

答案 5 :(得分:0)

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