clojure如何同时在两个seq的元素上执行函数?

clojure如何同时在两个seq的元素上执行函数?,clojure,Clojure,在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) 如何在不定义任何函数或宏的情况下实现这一点?map正是您所需要的,它接受一个函数和任意数量的s

在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)

如何在不定义任何函数或宏的情况下实现这一点?

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))
你也可以试试

(doseq [[x y] (map list my-list1 my-list2)]
  (println x y))
(映射列表列表-2列表-2)
创建一个列表,其中第一个元素是输入列表中第一个元素的列表,第二个元素是第二个元素的列表

然后,我们在列表上迭代,使用Clojure的解构来提取原始列表的元素


通常,如果要使用所应用函数的返回值,则需要
map
。如果您只是执行函数的副作用,我通常使用
doseq
。这个例子很复杂,因为
map
并行工作,而
doseq
迭代给定的列表,所以您需要
map
doseq
来获得我们想要的行为。

(doseq)的替代方案。。。(映射
解决方案,如果您想要成对迭代而不是笛卡尔积,您还可以将
分区
交错
组合,如下所示:

> (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
调用提供了一个(惰性)对序列。

@viebel:您是否在REPL上运行并使用
println
?如果是这样,您的结果会令人困惑。假设您运行了
(map#(println%1):“%2)ab)
,那么实际情况是REPL打印了
,然后
println
打印
0:100
1:101
,然后REPL完成地图结果的打印,即
nil-nil)
@Arthur Ulfeldt:我的问题的全部目的是寻找一种不创建映射的迭代方法。println只是一个例子。我寻找的代码应该与任何接收2个参数的函数一起工作。我是否应该编辑问题以澄清它?@viebel:
map
做了你想做的,但是
println
的结果是正确的e与REPL输出交错。
(map f a_1 a_2…a_n)
调用
f
,参数取自seqs
a_1
a_n
,并以新的
seq
println
返回
nil
,因此
map
ping
println
(nil-nil…nil)
结果。例如:
(map+[1 2 3][6 2 9][9 2 2])
=>
(16 6 14)
@YehonathanSharvit:
map
是懒惰的(请参阅,或者也有一点),因此它在需要结果之前不会进行计算(这也是REPL内容散布的原因)。它非常方便,但在这种情况下可能会绊倒您。请尝试
(doall(map println'(12)'(10 20))
doall
强制对传递给它的
seq
进行求值。(范围100 102)只有两个元素-也许您的意思是(范围100 103)?@mikera:谢谢。更新了问题:是否有类似doseq的函数可以并行迭代,而不是笛卡尔积。如果没有,背后的原理是什么?据我所知,没有这样的函数。理想情况下,doseq/for(它们的语法相同)将允许类似于:和的选项允许两个seq并行迭代。不幸的是,这样的选项不存在。