Hello!

When not using broadcasting, there is a way to destructure results from a function:

``````julia> f(x) = (x, x^2);

julia> (y1, y2) = f(5);

julia> y1
5

julia> y2
25
``````

However, this does not work while broadcasting:

``````julia> x = 1:10
1:10

julia> (z1, z2) = f.(x);

julia> z1
(1, 1)

julia> z2
(2, 4)
``````

Is there any way to do the same, and have in `z1` and `z2` arrays with the collection of the first and second arguments of the result respectively?

Sadly, no. The feature you want is `unzip`. There is a PR here which has not gotten merged into Base.

There is a package for this, though: Unzip.jl.

1 Like

notice this produces:

``````julia> f.(1:10)
10-element Vector{Tuple{Int64, Int64}}:
(1, 1)
(2, 4)
(3, 9)
(4, 16)
(5, 25)
(6, 36)
(7, 49)
(8, 64)
(9, 81)
(10, 100)
``````

which is not ideal storage in memory to begin with if youâ€™re interested in the â€ścolumnsâ€ť (in this display). you can do:

``````julia> [x^y for x in 1:10, y in 1:2]
10Ă—2 Matrix{Int64}:
1    1
2    4
3    9
4   16
5   25
6   36
7   49
8   64
9   81
10  100
``````

Sadly, thereâ€™s no syntax for multi dimensional comprehension (probably would be too confusing)

You can also do this with `StructArrays.jl`:

``````julia> using StructArrays

julia> using StructArrays: components

julia> z1, z2 = components(StructArray(f.(1:10)))
([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 4, 9, 16, 25, 36, 49, 64, 81, 100])
``````

edit: this naturally suggests

``````unzip(f, x) = components(StructArray(f(xáµ˘...) for xáµ˘ in x))
``````

which works well for multidimensional iterators:

``````julia> g(x, y) = x*y, y/x
g (generic function with 1 method)

julia> v1, v2 = unzip(g, Iterators.product(1:3, 1:4))
([1 2 3 4; 2 4 6 8; 3 6 9 12], [1.0 2.0 3.0 4.0; 0.5 1.0 1.5 2.0; 0.3333333333333333 0.6666666666666666 1.0 1.3333333333333333])

julia> v1
3Ă—4 Matrix{Int64}:
1  2  3   4
2  4  6   8
3  6  9  12
``````
1 Like

There is also Destruct.jl:

``````using Destruct
f(x) = (x, x^2)
x = 1:10
z1, z2 = f.(x) |> destruct
``````

This yields

``````z1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
z2 = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
``````