# Efficient method for Inserting arrays into arrays

This is strongly related to the following Questions:

I am looking for an efficient method to insert an array into an array. Let’s assume that both arrays have similar number of rows. Let’s further assume insertion is by column.

a = {{a1, b1, c1, d1, e1}, {a2, b2, c2, d2, e2}, {a3, b3, c3, d3, e3}}; (*example may be larger*)
b = {{x1, y1, z1}, {x2, y2, z2}, {x3, y3, z3}}; (*example may be larger*)


Q1: What is the fastest method to insert b into a at a position p. Let’s assume that both arrays have similar number of rows. Let’s further assume insertion is by column.

My current method is as follows:

insertarray[a_, b_, pos_] :=
FlattenAt[
Transpose@Insert[Transpose@a, b[[##]], pos ] & [Range[Length@a]],
Table[{i, pos}, {i, 1, Length@a}]];


which allows me to do

Q2: Some times I have to intersperse columns of b into a at multiple positions. How do I best extend insertarray so that:

insertarray[a,b,{1,2,5}]//MatrixForm


-
"Insertion" is not very well defined as shown unless a and b both have the same length. If this is the case, you should tell everyone that constraint. – VF1 Mar 21 '14 at 15:14
@VF1 a and b both have the same number of column elements... but yes, it would be better to be explicit whether the insertion is by row or column (esp. with square matrices) – R. M. Mar 21 '14 at 15:16
Edited for clarity. Added constraint insertion is by column. – Pam Mar 21 '14 at 15:17

### Q1

Join[a[[;; , ;; 1]], b, a[[;; , 2 ;;]], 2]


One may want to create function

insCol[a_, b_, n_] := Join[a[[;; , ;; n - 1]], b, a[[;; , n ;;]], 2]

insRow[a_, b_, n_] := Join[a[[;; n - 1]], b, a[[n ;;]]]

-
This one's really fast (and the cleanest solution, too) - good job! – VF1 Mar 21 '14 at 17:01
@VF1 Great you like it, thanks ;) – Kuba Mar 21 '14 at 17:36
I really like this solution. its very clean and does the job well… – Pam Mar 21 '14 at 17:59

After a few attempts, the following gives a noticeable if unremarkable improvement over insertarray:

columnInsert[a_, b_, pos_] :=
MapThread[Join[#1[[;; pos - 1]], #2, #1[[pos ;;]]] &, {a, b}];


Your second functionality doensn't actually need anything fancy, just some swaps afterwards:

SetAttributes[columnInsertswap, HoldFirst];
columnInsertswap[mat_, first_, list_] :=
Module[{i = first},
Scan[columnInserttmp = mat[[All, i]];
mat[[All, i++]] = mat[[All, #]];
mat[[All, #]] = columnInserttmp; &, list]; mat]
columnInsert[a_, b_, pos_List] :=
Module[{res = columnInsert[a, b, First@pos]},
columnInsertswap[res, First@pos, pos]; res]

-
VF1. Thanks. I tried the MapThread method as well… I was almost going to accept this as the solution… – Pam Mar 21 '14 at 18:01

I haven't had a chance to test if this is faster (probably not), but I find it easier to read:

Block[{x, T = Transpose}, Insert[T@a, x, 2] /. x -> Sequence @@ T@b // T]


or alternately:

MapThread[Flatten[## ~Insert~ 2] &, {a, b}]


Both give the following:

-
You beat me to the second one. I didn't find it much faster, though. One thing that sped it up slightly is Flatten[..., 1] – VF1 Mar 21 '14 at 15:34

Inserting b at column p :-

a = {{a1, b1, c1, d1, e1}, {a2, b2, c2, d2, e2}, {a3, b3, c3, d3, e3}};
b = {{x1, y1, z1}, {x2, y2, z2}, {x3, y3, z3}};

p = 4;

c = ReleaseHold@MapThread[Insert, {a, Hold[Sequence @@ #] & /@ b, Table[p, {Length@a}]}];

MatrixForm[c]


-
I tried something along these lines, but I found the additional ReleaseHold was too expensive - the whole expression needed to be traversed again for Hold`s. – VF1 Mar 21 '14 at 17:00
@VF1 - I wondered. It will be interesting to see the timings. – Chris Degnen Mar 21 '14 at 18:39