In Clojure, what is the best way for iterating concurrently on two seqs and calling a function on the two running elements? For example:
(def a (range 3))
(def b (range 100 103))
(defn my-func [] ...) ;some custom code
The code should execute my-func 3 times, like this:
(my-func 0 100)
(my-func 1 101)
(my-func 2 102)
How can I achieve that without defining any function or macro?
map
is exactly what you need, it takes a function and any number of seqs and calls them just as you wish.
(def a (range 3))
(def b (range 100 103))
user=> a
(0 1 2)
user=> b
(100 101 102)
user=> (defn my-func [a b] (str a ":" b))
#'user/my-func
user=> (my-func 1 2)
"1:2"
user=> (map my-func a b)
("0:100" "1:101" "2:102")
and because map
is lazy if you want the function to actually run now:
(doall (map my-func a b))
You could also try
(doseq [[x y] (map list my-list1 my-list2)]
(println x y))
(map list list-2 list-2)
creates a list where the first element is a list of the first elements of the input lists, the second element is a list of the second elements, ...
We then iterate over the list, using Clojure's destructuring to extract the elements of the original lists.
In general, you want map
if you want to use the return value of the function you are applying. If you are merely executing a function for its side effects, I generally use doseq
. This case is complicated by the fact that map
works in parallel, while doseq
iterates over the Cartesian Product of the lists it is given, so you need both map
and doseq
to get the behavior we want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With