Julia 矢量化喷溅

Julia 矢量化喷溅,julia,Julia,我希望能够以矢量化的方式将元组数组转换成函数。例如,如果我有以下函数 function foo(x, y) x + y end 以及下面的元组数组 args_array = [(1, 2), (3, 4), (5, 6)] 然后我可以使用列表理解来获得期望的结果: julia> [foo(args...) for args in args_array] 3-element Array{Int64,1}: 3 7 11 但是,我希望能够使用点矢量化符号进行此操作: j

我希望能够以矢量化的方式将元组数组转换成函数。例如,如果我有以下函数

function foo(x, y)
    x + y
end
以及下面的元组数组

args_array = [(1, 2), (3, 4), (5, 6)]
然后我可以使用列表理解来获得期望的结果:

julia> [foo(args...) for args in args_array]
3-element Array{Int64,1}:
  3
  7
 11
但是,我希望能够使用点矢量化符号进行此操作:

julia> foo.(args_array...)
ERROR: MethodError: no method matching foo(::Int64, ::Int64, ::Int64)
但正如您所看到的,这种特殊的语法不起作用。是否有一种矢量化的方法来执行此操作?

foo.(args\u数组…
不起作用,因为它正在执行以下操作:

foo.((1, 2), (3, 4), (5, 6))
# which is roughly equivalent to
[foo(1,3,5), foo(2,4,6)]
换句话说,它将
args_数组的每个元素作为一个单独的参数,然后在这些参数上广播
foo
。您希望直接在元素上广播
foo
。问题在于运行:

foo.(args_array)
# is roughly equivalent to:
[foo((1,2)), foo((3,4)), foo((5,6))]
换句话说,广播语法只是将每个元组作为单个参数传递给
foo
。我们可以通过一个简单的中间函数来解决这个问题:

julia> bar(args) = foo(args...);

julia> bar.(args_array)
3-element Array{Int64,1}:
  3
  7
 11
现在你想干什么就干什么!如果不想,甚至不需要构造第二个参数。这完全等同于:

julia> (args->foo(args...)).(args_array)
3-element Array{Int64,1}:
  3
  7
 11
事实上,你可以很容易地概括这一点:

julia> splat(f) = args -> f(args...);

julia> (splat(foo)).(args_array)
3-element Array{Int64,1}:
  3
  7
 11

您可以
zip
使用
args\u数组
,它可以有效地转换元组数组:

julia> collect(zip(args_array...))
2-element Array{Tuple{Int64,Int64,Int64},1}:
 (1, 3, 5)
 (2, 4, 6)
julia> foo.(zip(args_array...)...)
(3, 7, 11)
然后,您可以在元组的转置数组(实际上是一个迭代器)上广播
foo

julia> collect(zip(args_array...))
2-element Array{Tuple{Int64,Int64,Int64},1}:
 (1, 3, 5)
 (2, 4, 6)
julia> foo.(zip(args_array...)...)
(3, 7, 11)
但是,这将返回一个元组而不是数组。如果需要将返回值设置为数组,可以使用以下任何一种有点神秘的解决方案:

julia> foo.(collect.(zip(args_array...))...)
3-element Array{Int64,1}:
  3
  7
 11

julia> collect(foo.(zip(args_array...)...))
3-element Array{Int64,1}:
  3
  7
 11

julia> [foo.(zip(args_array...)...)...]
3-element Array{Int64,1}:
  3
  7
 11
怎么样

[foo(x,y) for (x,y) in args_array]

我喜欢
splat
功能
splat(foo)。(args_数组)
(在
splat(foo)
周围没有括号)在我的机器上工作。是的,额外的括号是多余的。如果有很多参数,这开始变得冗长,基本上相当于
[foo(args…)对于args_数组中的args]
,我在问题中提到过。