2013-03-10 15 views
4

我正在学习一些Clojure,我正在使用Quil。我想知道如何翻译一个for循环到Clojure的:如何在Clojure中进行for-loop?

这是我会怎么做它在Java或类似语言:

for (int i = 0; i < numSides; i++) { 
    float posX = cos(theta * i); 
    float posY = sin(theta * i); 
    ellipse(posX, posY, polySize, polySize); 
} 

我Clojure的尝试:

(let [theta (/ PI num-sides) 
     angle (range 0 num-sides) 
     pos-x (cos (* theta angle)) 
     pos-y (sin (* theta angle))] 
    (dorun (map #(ellipse % % % %) pos-x pos-y poly-size poly-size))) 
+0

发现了类似的问题在这里http://stackoverflow.com/questions/9981943/how-to-implement-a-for-loop-in-clojure – Forhad 2013-03-10 09:48:46

回答

6

你所寻找的所有方法基本上都是和序列一起工作的,因为循环就是执行特定次数的事情。 Clojure的提供dotimes为一定的次数做的事情:

(dotimes [i 10] 
    (println i)) 

所以,你的代码变得像:

(dotimes [i num-sides] 
    (let [pos-x (cos (* theta i)) 
     pos-y (sin (* theta i))] 
     (ellipse pos-x pos-y poly-size poly-size))) 
4

如果你真的想要一个C风格for循环,然后我clojure-utils libray有方便for循环宏,可以让你做的东西,如:

(for-loop [i 0 , (< i num-sides) , (inc i)] 
    ... do stuff.....) 

但是通常情况下,我会发现自己使用下列之一:

  • (dotimes [i num-sides] ....) - 做一些事情的时候
  • (doseq [x some-sequence] ....)一个具体的数字 - 做一些事情的每一个元素在序列
  • (for [i (range n)] ...) - 建设有n个元素的列表
+0

如何使我们可以这样做:'(for-loop [[i 1 j 1]( Ankur 2013-03-10 10:40:54

+0

@Ankur有趣的想法....自己并不需要,但可以看到一些用例的价值。 – mikera 2013-03-10 10:56:12

2

这也许是有点学术,但我喜欢使用Clojure的“理解”这类东西。该代码是这样的:

(dorun 
    (for [i (range num-sides) 
     :let [pos-x (Math/cos (* i theta)) 
       pos-y (Math/sin (* i theta))]] 
    (quil.core/ellipse pos-x pos-y poly-size poly-size))) 
+0

但是在这种情况下'for'构造了一个不必要的惰性序列。如果你不需要输出序列,就像在这种情况下一样,你可以用'doseq'来做同样的事情 - 使用相同的绑定技巧。只需在上面的代码中用'doseq'替换'for'即可。在许多情况下,生成附加序列的成本可以忽略不计,因此'doseq'的唯一优点是它向读者传达了您不想创建序列的问题。但是,在某些情况下,创建不必要序列的成本可能会影响性能。 – Mars 2014-08-23 04:37:01

1

Doseqrange通常适用于以创建副作用遍历值的具体数量。我想实现如下的循环:

(doseq [i (range 0 num-sides)] 
    (ellipse (cos (* theta i)) 
      (sin (* theta i)) 
      poly-size 
      poly-size)) 
相关问题