2013-03-10 59 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)) 
相關問題