Double broadcast

I frequently find myself wishing to do a double broadcast, e.g.:

f = x->x+1
(v -> f.(v)).( [[1,2,3], [4,5,6]])

Is this the most concise way to do it?

1 Like

since a function is not iterable, you could do

map.(f,[[1,2,3],[4,5,6]])

or make use of dispatch

julia> f(x) = x+1
f (generic function with 1 method)

julia> f(x::AbstractArray) = f.(x)
f (generic function with 2 methods)

julia> f.([[1,2,3],[4,5,6]])
2 Likes

I never thought about broadcasting map before cause I’ve definitely also done (v -> f.(v)).( [[1,2,3], [4,5,6]]) before. That’s an interesting workaround! It also reminds me of the opposite “half broadcast” trick f.(Ref([1,2,3]), [4,5,6]) to result in [f([1,2,3], 4), f([1,2,3], 5], ...].

For completeness, another option is

julia> Broadcast.BroadcastFunction(f).( [[1,2,3], [4,5,6]])
2-element Vector{Vector{Int64}}:
 [2, 3, 4]
 [5, 6, 7]

julia> Broadcast.BroadcastFunction(Broadcast.BroadcastFunction(f))( [[1,2,3], [4,5,6]]) # same, but replace the . with BroadcastFunction
2-element Vector{Vector{Int64}}:
 [2, 3, 4]
 [5, 6, 7]

julia> .+ # it's the same machinery used by dotted operators
Base.Broadcast.BroadcastFunction(+)

It’s equivalent to your v -> f.(v) anonymous function, although I would say it’s at least as ugly. But I’ll leave it here anyway as someone might find it useful for nesting multiple layers of broadcasting. Although for nested broadcasting, dispatch-based recursion (as mentioned above) is often nicer.

I generally use nested array comprehension for this type of problem.

[ [x+1 for x in v] for v in [[1,2,3], [4,5,6]] ]