在Clojure中,在两个seq上并发迭代并在两个运行元素上调用函数的最佳方法是什么? 例如:
(def a (range 3))
(def b (range 100 103))
(defn my-func [] ...) ;some custom code
代码应该执行my-func 3次,如下所示:
(my-func 0 100)
(my-func 1 101)
(my-func 2 102)
如何在不定义任何功能或宏的情况下实现这一目标?
答案 0 :(得分:16)
map
正是您所需要的,它需要一个函数和任意数量的seq,并按照您的意愿调用它们。
(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")
并且因为map
是懒惰的,如果你想让函数实际上立即运行:
(doall (map my-func a b))
答案 1 :(得分:3)
您也可以尝试
(doseq [[x y] (map list my-list1 my-list2)]
(println x y))
(map list list-2 list-2)
创建一个列表,其中第一个元素是输入列表的第一个元素的列表,第二个元素是第二个元素的列表,...
然后我们使用Clojure的解构迭代列表,以提取原始列表的元素。
通常,如果要使用要应用的函数的返回值,则需要map
。如果您只是为其副作用执行函数,我通常使用doseq
。 map
并行工作,doseq
遍历列表的Cartesian Product,因此需要map
和{{} 1}}以获得我们想要的行为。
答案 2 :(得分:0)
(doseq ... (map
解决方案的替代方案,如果您想要成对迭代而不是笛卡尔积,您还可以将partition
与interleave
合并为:
> (def a (range 0 3))
> (def b (range 100 103))
> (interleave a b)
(0 100 1 101 2 102)
> (partition 2 (interleave a b))
((0 100) (1 101) (2 102))
partition
调用提供(懒)seq对。