# Inplace conversion of a (m,n)-array into an m-element array

Hi everyone,

I’m new to Julia, comming from Python. I was a bit confused when defining an array as a list of lists in Python, I noticed that it isn’t an array of size(m,n).
I searched the WEB and here, for an inplace conversion of an array of size (m,n) to an m-element array, but couldn’t find any example/reference. Is such a conversion possible?
Example, if I have an array:

``````arr =  rand(1:15, (3,4))
3×4 Array{Int64,2}:
6   8   8  13
4   3  14   6
14  13   1  12
``````

I need to convert it inplace into:

``````[[6, 8, 8, 13],
[4, 3, 14, 6],
[14, 13, 1, 12]]
``````

At the moment I defined the associated m-element array by:

``````elarr = [arr[k, :] for k in 1:m]
``````

but for a big m and n it is memory consuming to have both `arr` and `elarr` defined.

Julia is column-major, so it’ll be faster to flip your array’s indices and use column-wise slices. Try `collect(eachcol(arr))`, or `eachrow` if you really need the rows for some reason.

``````julia> arr =  rand(1:15, (3,4))
3×4 Array{Int64,2}:
9  14   9  1
5   8  13  5
4  13  15  4

julia> collect(eachcol(arr))
4-element Array{SubArray{Int64,1,Array{Int64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true},1}:
[9, 5, 4]
[14, 8, 13]
[9, 13, 15]
[1, 5, 4]
``````
4 Likes

If you really need it to be in-place (meaning, sharing the same data in RAM), then you should use `reinterpret` in conjunction with StaticArrays.jl:

``````julia> arr =  rand(1:15, (3,4))
3×4 Matrix{Int64}:
2  8  14  14
11  9   6   9
6  3   5  12

julia> using StaticArrays

julia> av1 = reinterpret(SVector{3,Int}, arr)
1×4 reinterpret(SVector{3, Int64}, ::Matrix{Int64}):
[2, 11, 6]  [8, 9, 3]  [14, 6, 5]  [14, 9, 12]
``````

Because Julia is column-major, each column of `arr` has been turned into a vector. You specify the column size as the first parameter to `SVector`.

On the not-yet-released Julia 1.6, you also have the option to simultaneously reshape into a vector:

``````julia> av2 = reinterpret(reshape, SVector{3,Int}, arr)     # requires Julia 1.6
4-element reinterpret(reshape, SVector{3, Int64}, ::Matrix{Int64}) with eltype SVector{3, Int64}:
[2, 11, 6]
[8, 9, 3]
[14, 6, 5]
[14, 9, 12]
``````
5 Likes

My `eachcol` solution should be in-place, unless there’s some nuance I’m missing:

``````julia> collect(eachcol(arr))[1][1] = 100
100

julia> arr
3×4 Array{Int64,2}:
100  14   9  1
5   8  13  5
4  13  15  4
``````
1 Like

I think that you are right, but in versions before Julia 1.5 your solution may lead to more allocations (because views may allocate and your alternative generate a view for each column).

@tim.holy

Thank you for your suggestion. I have to dig deeper into StaticArrays, because I’m only 7 days old with Julia.

You’re right, thanks for the correction. Some people use in-place to mean “no allocation” but your definition is really the right one.

2 Likes