I have a vector V1 of length m where each element is a vector of length n.
How do I “transpose” that into a vector V2 of length n where each element is a vector of length m and V2[i][j] == V1[j][i]?

As an example:

V1 = [rand(3) for x in 1:10]
V2 = [[x[1] for x in V1], [x[2] for x in V1], [x[3] for x in V1]]
julia> V1[7][2] == V2[2][7]
true

This is doable for n small, but there must be a more general solution.

Thank you all. This is such a great community!
So much to choose from.
I’ll definitely look more into TensorCast.jl and SplitApplyCombine.jl

Here’s a quick comparison, where especially TensorCast is really impressive:

using TensorCast, SplitApplyCombine
function transpose_tensor(V1)
@cast V2[i][j] := V1[j][i]
V2
end
function transpose_comprehension(V1)
[[x[i] for x in V1] for i in eachindex(V1[1])]
end
function transpose_funct(V1)
collect(eachrow(reduce(hcat, V1)))
end
function transpose_invert(V1)
invert(V1)
end
using BenchmarkTools
julia> @btime transpose_tensor(data) setup=(data=[rand(5) for x in 1:500]);
545.250 ns (4 allocations: 344 bytes)
julia> @btime transpose_comprehension(data) setup=(data=[rand(5) for x in 1:500]);
6.287 μs (6 allocations: 20.44 KiB)
julia> @btime transpose_funct(data) setup=(data=[rand(5) for x in 1:500]);
5.119 μs (3 allocations: 19.92 KiB)
julia> @btime transpose_invert(data) setup=(data=[rand(5) for x in 1:500]);
5.318 μs (6 allocations: 20.44 KiB)

Please note that the := syntax in TensorCast returns a view, thus the greater speed observed. If |= was used to create a copy, then the time would be comparable to the other solutions. @mcabbott can advise.