# Insert at specific resulting positions?

I have an initial list:

list0 = {1,2,3,4,5};


and I want to insert {a,x} at specific positions {1,5}, which means that I want the resulting list to have a at position 1 and x at position 5. This is different from what Mathematica's Insert does, and what has been asked here before (Looking for a way to insert multiple elements into multiple positions simultaneously in a list). In my example, the output I expect is:

In[]: myInsert[list0, {a,x}, {1,5}]
Out[]: {a,1,2,3,x,4,5}


What's a clean way to do this? And what's a good name for this type of insertion?

Multidimensional version: Insert at specific resulting positions in multidimensional list?

• What would be the result of myInsert[list0,{a,x},{4,1}], {x,1,2,a,3,4,5} or {x,1,2,3,a,4,5} ? Dec 4, 2014 at 17:03
• @andre myInsert[list0,{a,x},{4,1}] should output {x,1,2,a,3,4,5}. The list of positions {4,1} gives the positions of the inserted elements in the resulting list.
– a06e
Dec 4, 2014 at 17:05
• @andre Thanks for pointing out that the positions list should be sorted ;)
– a06e
Dec 4, 2014 at 17:28
• related (newer) question mathematica.stackexchange.com/q/129294/2079 Oct 22, 2016 at 12:37

## 2 Answers

Fold[Insert[#, #2[[1]], #2[[2]]] &, list0, {{a, 1}, {x,5}}]
(* {a, 1, 2, 3, x, 4, 5} *)


Or, define a function:

insertF = Fold[Insert[#, #2[[1]], #2[[2]]] &, #,  SortBy[Transpose[{#2, #3}], Last]] &;
(* thanks: @becko *)

insertF[Range@5, {a, x}, {1, 4}]
(* {a, 1, 2, x, 3, 4, 5} *)
insertF[Range@5, {a, w, x}, {1, 5, 4}]
(* {a, 1, 2, x, w, 3, 4, 5} *)

• The line of code Fold[Insert[#, #2[[1]], #2[[2]]] &, list0, {{a, 1}, {x,5}}] gives what I want. However the function insertF as you defined it doesn't. In your example with the function, x should be inserted at position 4 of the resulting list.
– a06e
Dec 4, 2014 at 17:09
• In think the Accumulate@#3 is the problem. Replacing it with just #3 works.
– a06e
Dec 4, 2014 at 17:10
• @becko, you are right; still trying to fix it :).
– kglr
Dec 4, 2014 at 17:12
• I think that insertF = Fold[Insert[#, #2[[1]], #2[[2]]] &, #, SortBy[Transpose[{#2, #3}], Last]] &; works.
– a06e
Dec 4, 2014 at 17:27
• @becko, oh, just saw the edit in your question... realized i was trying to solve the wrong question:)
– kglr
Dec 4, 2014 at 17:38

I found a rather simple way to do what I want:

myInsert[list_, val_, pos_] :=
Insert[list, val, List /@ (Sort@pos - Range@Length@pos + 1)]


Example:

In[]:= myInsert[Range@5, x, {1, 5}]
Out[]= {x, 1, 2, 3, x, 4, 5}


However, this inserts only inserts copies of the same element, and I haven't come up with a good name for this yet.

• It appears that this answer is not quite what the question poser needs, since the Output does not match the desired Output. The problem with the proposed solution is that the counting of insertion index should occur BEFORE insertion of any elements, not AFTER. Dec 4, 2014 at 16:59
• @DavidG.Stork I disagree. This produces the desired output (I am the OP ;)). Please tell me why you think this is not consistent with what I asked.
– a06e
Dec 4, 2014 at 17:04
• You stated you wanted this output: {a,1,2,3,x,4,5} but the code above produced this output: {x,1,2,a,3,4,5}. @Andre asked my same question: 'What would be the result of myInsert[list0,{a,x},{4,1}], {x,1,2,a,3,4,5} or {x,1,2,3,a,4,5}?' Dec 4, 2014 at 18:32
• @DavidG.Stork Yes. As I explain in the answer, this method doesn't allow inserting multiple elements. It only inserts copies of the same element. Hence I obtain {x, 1, 2, 3, x, 4, 5}
– a06e
Dec 4, 2014 at 18:33
• The issue is not whether multiple elements can be inserted but instead the LOCATION of the insertions. As @Andre's question shows, there was an ambiguity about whether there should be TWO elements of list0 that separate the "x" and "a" or instead THREE elements that separate the "x" and "a". It seems, moreover, that there has been a change in the code from specifying insertion points as {1,4} to {1,5}, further complicating the discussion. Dec 4, 2014 at 18:46