我想在Clojure中实现这个小代码,但我很挣扎:
struct mystruct {
int id;
int price;
};
mystruct mydata[10];
for (int i=0; i<10; i++) {
myfunction(mydata[i].id, mydata[i].price);
//other things...
}
我是Clojure的初学者,我做这样简单的事情真的很复杂,但我真的很想学习,因为我知道Clojure有很大的优势,比如使用refs ......
如果有人能帮助我,我真的很感激。谢谢!
答案 0 :(得分:36)
将循环命令转换为Clojure的一种方法是使用for
宏。
(for [i (range 10)] (inc i))
上面的函数将返回0到9之间的所有数字,加1。但是,您似乎只想迭代顺序集合并使用每个项目。如果这就是您需要的全部内容,那么您不需要引用索引值,而是可以直接引用每个项目。
(for [d my-vec-of-data] (my-function d))
但是,对于这个简单的情况,map
函数可能是更好的选择,因为它被设计为使用来自集合的参数调用函数。以下示例相当于使用上面的for
。
(map my-function my-vec-of-data)
map
和for
都会返回由my-function
返回的值组成的值集合。这是因为Clojure的数据结构是不可变的,因此必须返回一个新的集合。如果这不是您所需要的,或者您的功能有副作用,则可以使用doseq
代替for
,而nil
会返回{{1}}。
答案 1 :(得分:33)
Jeremy的答案对于如何在惯用的Clojure中进行for循环很有用。
如果你真的想在Clojure中使用命令式样式for循环,你可以用这个宏创建一个:
(defmacro for-loop [[sym init check change :as params] & steps]
`(loop [~sym ~init value# nil]
(if ~check
(let [new-value# (do ~@steps)]
(recur ~change new-value#))
value#)))
用法如下:
(for-loop [i 0 (< i 10) (inc i)]
(println i))
答案 2 :(得分:1)
doseq
的作用类似于 for-loop
用法:
(doseq [i (for [i (range 10)] (inc i))]
(println "i=" i))
绑定类似于Clojure中的for
。但是,它不会通过评估 doseq
内的表达式来返回列表。它为序列中的每个值执行表达式并返回 nil
。
要循环一个 seq,您可以简单地使用:
(doseq [value list]
(println "Your expression here" value)