我希望能够以向量化的方式将一个元组数组喷射到一个函数中。例如,如果我具有以下功能,
function foo(x, y)
x + y
end
Run Code Online (Sandbox Code Playgroud)
和以下元组数组,
args_array = [(1, 2), (3, 4), (5, 6)]
Run Code Online (Sandbox Code Playgroud)
然后我可以使用列表推导来获得所需的结果:
julia> [foo(args...) for args in args_array]
3-element Array{Int64,1}:
3
7
11
Run Code Online (Sandbox Code Playgroud)
但是,我希望能够对此操作使用点矢量化表示法:
julia> foo.(args_array...)
ERROR: MethodError: no method matching foo(::Int64, ::Int64, ::Int64)
Run Code Online (Sandbox Code Playgroud)
但是如您所见,该特定语法不起作用。有矢量化的方法可以做到这一点吗?
foo.(args_array...) 不起作用,因为它正在执行以下操作:
foo.((1, 2), (3, 4), (5, 6))
# which is roughly equivalent to
[foo(1,3,5), foo(2,4,6)]
Run Code Online (Sandbox Code Playgroud)
换句话说,它将每个元素args_array作为一个单独的参数,然后广播foo这些参数。您要foo直接广播元素。问题是运行:
foo.(args_array)
# is roughly equivalent to:
[foo((1,2)), foo((3,4)), foo((5,6))]
Run Code Online (Sandbox Code Playgroud)
换句话说,广播语法只是将每个元组作为单个参数传递给foo。我们可以用一个简单的中间函数来解决这个问题:
julia> bar(args) = foo(args...);
julia> bar.(args_array)
3-element Array{Int64,1}:
3
7
11
Run Code Online (Sandbox Code Playgroud)
现在,这就是您想要的!如果不想的话,甚至不需要构造第二个参数。这是完全等效的:
julia> (args->foo(args...)).(args_array)
3-element Array{Int64,1}:
3
7
11
Run Code Online (Sandbox Code Playgroud)
实际上,您可以很容易地对此进行概括:
julia> splat(f) = args -> f(args...);
julia> (splat(foo)).(args_array)
3-element Array{Int64,1}:
3
7
11
Run Code Online (Sandbox Code Playgroud)