I'd like to implement this little code in Clojure, but I am struggling:
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...
}
I am a beginner with Clojure and it's really complicated for me to do something simple like this, but I am really trying to learn as much as possible as I know that there are great advantages with Clojure such as using refs...
I would really appreciate it if somebody could help me. Thanks!!
One way to translate an imperative for loop to Clojure is to use the for
macro.
(for [i (range 10)] (inc i))
The above function will return all the numbers from 0 to 9 incremented by 1. However, it appears you simply want to iterate over a sequential collection and use each item. If that's all that you need, then you don't need to reference an index value, instead you can reference each item directly.
(for [d my-vec-of-data] (my-function d))
However, for this simple case, the map
function would probably be a better choice because it is designed to invoke functions with arguments from collections. The following example is equivalent to the use of for
above.
(map my-function my-vec-of-data)
Both map
and for
return a collection of values made up of the values returned by my-function
. This is because Clojure's data structures are immutable, so it's necessary to have a new collection returned. If that isn't what you need or if your function has side effects, you could use doseq
instead of for
, which returns nil
.
Jeremy's answer is good for how to do a for loop in idiomatic Clojure.
If you really want an imperative-style for loop in Clojure, you can create one with this macro:
(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#)))
Usage as follows:
(for-loop [i 0 (< i 10) (inc i)]
(println i))