How to extract components in an array of arrays

Suppose I have an array of arrays, say a 2 x 2 matrix whose entries are 1 x 2 vectors, e.g.,

julia> A
2×2 Matrix{Matrix{Int64}}:
 [1 2]  [3 4]
 [5 6]  [7 8]

I am wondering, without using for loops, how to extract a 2 x 2 matrix consisting of the 1st entries of this matrix of matrices, i.e.,

2x2 Matrix{Int64}
1 3
5 7

Also, a matrix of its 2nd entries, i.e.,

2x2 Matrix{Int64}
2 4
6 8

Is there a nice and quick way to do this? (Of course, what I really want is to do the same for large matrices of matrices or vectors, but this 2x2 example sufficiently describe my intention.)
Thanks a lot in advance!

You can broadcast getindex.(A,1) which gets index 1 for each element of the array.

Thank you so much! This is quite helpful!

Specifically for the first and last elements, you can use first.(A) and last.(A).

BTW, there’s no such thing as a 1x2 vector. That is a matrix.

Note that in Julia vocab, [1 2] is not a vector but a 1x2 matrix. If you don’t have a specific reason to store your data like this, using [1, 2] is more Julian.

what is (are they?) the syntax to use to build by hand a matrix like A that has matrices as elements?

The following reproduces A:

A = [[[1 2]] [[3 4]]; [[5 6]] [[7 8]]]  

I have tried these ways, but one doesn’t work and I didn’t like the other as much

julia> [[1 2] [3 4]; [5 6] [7 8]]
2×4 Matrix{Int64}:
 1  2  3  4
 5  6  7  8

julia> reshape([[1 2], [5 6], [3 4], [7 8]],2,2)
2×2 Matrix{Matrix{Int64}}:
 [1 2]  [3 4]
 [5 6]  [7 8]

instead, this creates an array of tuples.
Why in the case of vectors need to be wrapped inside another vector?

julia> [(1,2) (3,4); (5,6) (7,8)]
2×2 Matrix{Tuple{Int64, Int64}}:
 (1, 2)  (3, 4)
 (5, 6)  (7, 8)

anhoter way

julia> [[[1 2], [5 6]] [ [3 4], [7 8]]]
2×2 Matrix{Matrix{Int64}}:
 [1 2]  [3 4]
 [5 6]  [7 8]

I think this follows from Julia’s rule that square braces surrounding elements separated by spaces are equivalent to horizontal concatenation:

[A B] == hcat(A,B)

Thanks, you are right. What I meant was row vectors of length 2, which are 1 x 2 matrices.

BTW, what I really wanted to do is to generate a vector field on a 2D plane, say, the unit square, and draw that vector field using quiver plot in Plots.jl. So, here is an example on a very small grid.

julia> using LazyGrids # this allows to generate meshes like in MATLAB
julia> X, Y = ndgrid((collect(0:1), collect(0:1));
julia> X
2×2 LazyGrids.GridAV{Int64, 1, 2}:
 0  0
 1  1
julia> Y
2×2 LazyGrids.GridAV{Int64, 2, 2}:
 0  1
 0  1
julia> f(x,y) = [0.0 1.0; 1.0 0.0] * [x; y]; # Just a simple example of generating a vector at (x,y).
julia> A =  f.(X,Y) # pointwise evaluation of f on the mesh
2×2 Matrix{Vector{Float64}}:
 [0.0, 0.0]  [1.0, 0.0]
 [0.0, 1.0]  [1.0, 1.0]

Then, in order to use quiver plot, I need to extract the first components and the second components:

quiver(X[:], Y[:], quiver=(getindex.(A,1)[:], getindex.(A,2)[:]))

Perhaps, there is a better way to generate a vector field, which can easily supply to the quiver plot…

It should be more convenient to work with vectors as they are, instead of separate components:

julia> using RectiGrids
julia> using StaticArrays

# array of SVectors, instead of two separate arrays:
julia> XY = grid(SVector, 0:1, 0:1) 
2-dimensional KeyedArray(...) with keys:
↓   2-element UnitRange{Int64}
→   2-element UnitRange{Int64}
And data, 2×2 RectiGrids.RectiGridArr{Base.OneTo(2), SVector{2, Int64}, 2, Tuple{UnitRange{Int64}, UnitRange{Int64}}}:
      (0)        (1)
 (0)     [0, 0]     [0, 1]
 (1)     [1, 0]     [1, 1]

# f() takes the whole svector, not two separate components:
julia> f(xy) = [0. 1; 1 0] * xy
f (generic function with 1 method)

julia> A = f.(XY)
2-dimensional KeyedArray(...) with keys:
↓   2-element UnitRange{Int64}
→   2-element UnitRange{Int64}
And data, 2×2 Matrix{Vector{Float64}}:
      (0)            (1)
 (0)     [0.0, 0.0]     [1.0, 0.0]
 (1)     [0.0, 1.0]     [1.0, 1.0]

Only in the end, if you actually need to split them into components:

julia> using SplitApplyCombine

julia> invert(XY)
2-element Vector{Matrix{Int64}}:
 [0 0; 1 1]
 [0 1; 0 1]

julia> invert(A)
2-element Vector{Matrix{Float64}}:
 [0.0 1.0; 0.0 1.0]
 [0.0 0.0; 1.0 1.0]