Array of tuples to tuple of arrays

Background: a function returns a tuple, and then I call on it using the dot syntax with an array as input. The output will be an array of tuples, but I want a tuple of arrays. My example and solution is below. The question: is this solution any good or are there obvious things to improve?

function fn1(a)
  x = a/2
  y = a*2
  return x, y
end

z = fn1.(1:3)                         #an array of tuples   
(x,y) = ntuple(i->getindex.(z,i),2)   #a tuple of arrays 

I just always use StructArrays.jl for this type of stuff nowadays, so I’ll plug that here.

4 Likes

Yes, StructArrays can handle conversion from Array of structs (either struct, or NamedTuple or Tuple) to a NamedTuple of Arrays (in terms of storage, but it still allows accessing the rows). For example:

julia> using StructArrays

julia> v = [(1, "a"), (2, "b")];

julia> s = StructArray(v)
2-element StructArray{Tuple{Int64,String},1,NamedTuple{(:x1, :x2),Tuple{Array{Int64,1},Array{String,1}}}}:
 (1, "a")
 (2, "b")

julia> s[1]
(1, "a")

julia> values(StructArrays.columns(s))
([1, 2], ["a", "b"])

Keeping things stored as a a StructArray is a flexible solution as you get both the tuple of vectors if you need, but at the same time can access the rows as tuples.

2 Likes

There is a more direct route, if it just needs to apply to that function

function fn2(a)
  return a./2, a.*2
  end;

(x,y) = fn2(z)