How to append a matrix element by element?

To join nested arrays elementwise, use the third argument of Join. For matrices, depth 1 (default) is rows, 2 is columns, and 3 is elements.

a = Array[{}&, {2,2}];

b = {
{b1, b2},
{b3, b4}
};

listEach = Map[List, #, {2}]&

appendEach[x_,y_] := Join[x, listEach[y], 3]

Print[appendEach[appendEach[a, b], b+5]]
(* {{{b1, 5 + b1}, {b2, 5 + b2}}, {{b3, 5 + b3}, {b4, 5 + b4}}} *)

Try it online!

However, if you are appending many matrices it may be more efficient to create a list of matrices using Sow / Reap, then Transpose into a matrix of lists.


Update:

ClearAll[f1, f2]
f1 = MapThread[List, #, 2] &;
f2 = Flatten[#, {{2}, {3}}] &;

Using Carl's example setup:

SeedRandom[1]
{a, b, c, d} = RandomInteger[1, {4, 2, 2}];

f1[{a, b, c, d}]

{{{1, 0, 0, 0}, {1, 0, 1, 0}}, {{0, 0, 0, 0}, {1, 1, 0, 0}}}

f2[{a, b, c, d}] == f1[{a, b, c, d}] == Transpose[{a, b, c, d}, {3, 1, 2}]

True

If some input matrices might have {} as an element all methods above retain {}s in the combined matrix:

f1[{a, A, c, d}]

{{{1, {}, 0, 0}, {1, {}, 1, 0}}, {{0, {}, 0, 0}, {1, {}, 0, 0}}}

MapThread with Flatten[{##}] & as the first argument eliminates {}s:

MapThread[Flatten[{##}] &, {a, A, c, d}, 2] 

{{{1, 0, 0}, {1, 1, 0}}, {{0, 0, 0}, {1, 0, 0}}}

Original answer:

MapThread Flatten at Level 2:

MapThread[Flatten[{##}] &, {A, B}, 2]

{{{a}, {b}}, {{c}, {d}}}


Suppose you have 4 matrices:

SeedRandom[1]
{a, b, c, d} = RandomInteger[1, {4, 2, 2}];

Then, you can use Transpose to construct the desired matrix:

Transpose[{a, b, c, d}, {3, 1, 2}]

{{{1, 0, 0, 0}, {1, 0, 1, 0}}, {{0, 0, 0, 0}, {1, 1, 0, 0}}}