Going to flat_x
you can use
julia> reduce(vcat, array_x)
12-element Vector{Int64}:
1
1
1
1
2
2
2
2
3
3
3
3
which will allocate a new (contiguous) array. There might be non-allocating approaches, but then you would be working with non-contiguous memory, which might also not be ideal.
For the converse direction you can use
julia> eachrow(reshape(flat_x, 4, 3)')
3-element RowSlices{LinearAlgebra.Adjoint{Int64, Matrix{Int64}}, Tuple{Base.OneTo{Int64}}, SubArray{Int64, 1, LinearAlgebra.Adjoint{Int64, Matrix{Int64}}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, false}}:
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]
or if the number of columns is fixed, statically known, and relatively small
julia> using StaticArrays
julia> reinterpret(SVector{4, Int64}, flat_x)
3-element reinterpret(SVector{4, Int64}, ::Vector{Int64}):
[1, 1, 1, 1]
[2, 2, 2, 2]
[3, 3, 3, 3]