1

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?

a06e
  • 11,327
  • 4
  • 48
  • 108
  • 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} ? – andre314 Dec 04 '14 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 04 '14 at 17:05
  • @andre Thanks for pointing out that the positions list should be sorted ;) – a06e Dec 04 '14 at 17:28
  • related (newer) question http://mathematica.stackexchange.com/q/129294/2079 – george2079 Oct 22 '16 at 12:37

2 Answers2

4
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} *)
kglr
  • 394,356
  • 18
  • 477
  • 896
  • 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 04 '14 at 17:09
  • In think the Accumulate@#3 is the problem. Replacing it with just #3 works. – a06e Dec 04 '14 at 17:10
  • @becko, you are right; still trying to fix it :). – kglr Dec 04 '14 at 17:12
  • I think that insertF = Fold[Insert[#, #2[[1]], #2[[2]]] &, #, SortBy[Transpose[{#2, #3}], Last]] &; works. – a06e Dec 04 '14 at 17:27
  • @becko, oh, just saw the edit in your question... realized i was trying to solve the wrong question:) – kglr Dec 04 '14 at 17:38
  • Sorry about that. I had a typo. – a06e Dec 04 '14 at 17:38
  • @becko, no worries:) – kglr Dec 04 '14 at 17:39
1

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.

a06e
  • 11,327
  • 4
  • 48
  • 108
  • 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. – David G. Stork Dec 04 '14 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 04 '14 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}?' – David G. Stork Dec 04 '14 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 04 '14 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. – David G. Stork Dec 04 '14 at 18:46