1
$\begingroup$

I wanted to write myself a function that makes it possible to Insert several rows into one list.

matrix = Table[i*(j + 2), {i, 3}, {j, 3}];
vector1 = Range[10, 12];
vector2 = Range[20, 22];

This one worked perfectly fine:

Do[matrix = Insert[matrix, {vector1, vector2}[[i]], 1], {i, 2}];

Then I started straightforward with:

InsertRows[vectors_List, matrix_List, position_Integer] :=
Do[
matrix = Insert[matrix, vectors[[i]], position]
, {i, Length@vectors}]

This does not work. After little search I found that I have to force Do[] to return some value. But the same search also highlighted that it is not recommended to use Return[].

So here are my questions:

  1. How to define a function that can insert several rows. If there is an approach without a loop, I was happy to see it.
  2. How to properly define this function with the Do[] Loop.
$\endgroup$
2
  • 1
    $\begingroup$ What error do you get with your version of InsertRows when I copy and paste it into mathematica for vectors_list and matrix_list, "list" I get lower case l's $\endgroup$ Jun 12, 2015 at 13:36
  • 1
    $\begingroup$ I changed _list to _List. Sorry for the typo. $\endgroup$
    – mcocdawc
    Jun 12, 2015 at 14:06

2 Answers 2

4
$\begingroup$

the main issue is that you cannot (readily*) modify the actual argument to a function Try this:

 InsertRows[vectors_List, matrix0_List,position_Integer] := 
   Module[{matrix},
       matrix = matrix0;
       Do[matrix = Insert[matrix, vectors[[i]], position], {i, 
           Length@vectors}]; matrix]

usage: matrix = InsertRows[{vector1, vector2}, matrix, 1]

*of course it can be done using HoldFirst but its best avoided: (note no _List on matrix )

 InsertRows[matrix_, vectors_List, position_Integer] := Module[{},
      Do[matrix = Insert[matrix, vectors[[i]], position], {i, 
         Length@vectors}]]
 SetAttributes[InsertRows, HoldFirst]

usage: InsertRows[matrix,{vector1, vector2}, 1] modifies the arg and returns Null.

Of course in either case the Do loop is best replaced per @image_doctor's answer -- another variant is Join[matrix[[;; position - 1]], vectors, matrix[[position ;;]]]

$\endgroup$
1
  • $\begingroup$ Thank you very much for both your answers. I gave image_doctor the Question Solved sign since you already have more reputation ;). $\endgroup$
    – mcocdawc
    Jun 12, 2015 at 14:43
4
$\begingroup$

Here are a couple of approaches without using a loop, but utilising Flatten and FlattenAt:

FlattenAt[Insert[matrix, {vector1, vector2}, 2], 2]

{{3, 4, 5}, {10, 11, 12}, {20, 21, 22}, {6, 8, 10}, {9, 12, 15}}

ir[vecs_, matrix_, pos_] := Flatten[{matrix[[1 ;; pos - 1]], vecs, matrix[[pos ;; -1]]}, 1]

ir[{vector1, vector2}, matrix, 2]

{{3, 4, 5}, {10, 11, 12}, {20, 21, 22}, {6, 8, 10}, {9, 12, 15}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.