I need to change the position of a single element in a list. Example: I start with:


I want to move the a before the d to get:


How would I do this? Thank you!


6 Answers 6

data = {a, b, c, d, e, f};
Permute[data, {3, 1, 2}]


Permute[data, Cycles[{{1, 3, 2}}]]

Both give

{b, c, a, d, e, f}


It occurred to me that it would be good to be able to move an element to a lower position in the list as well as a higher one. Together the following two functions give both capabilities.

Upward movement -- move an element at position m to position n, where m < n:

moveElementUp[data_List, m_Integer /; m > 0, n__Integer /; n > 0] /; m < n :=
  Permute[data, Join[Range[m - 1], {n}, Range[m, n - 1]]]

moveElementUp[data, 1, 3]
{b, c, a, d, e, f}
moveElementUp[data, 2, 5]
{a, c, d, e, b, f}
moveElementUp[data, 1, 6]
{b, c, d, e, f, a}

Downward movement -- move an element at position m to position n, where m > n:

moveElementDown[data_List, m_Integer /; m > 0, n__Integer /; n > 0] /; m > n :=
  Permute[data, Join[Range[n - 1], 1 + Range[n, m - 1], {n}]]

moveElementDown[data, 3, 1]
{c, a, b, d, e, f}
moveElementDown[data, 5, 3]
{a, b, e, c, d, f}
moveElementDown[data, 6, 1]
{f, a, b, c, d, e}


Although I found it interesting to attack this problem with permutations, I suspect there is a better solution.


The following answer is effectively equivalent to m_goldberg's answer, except that the distinction between the two directions of movement has been eliminated:

moveElement[l_List, m_Integer?Positive, n_Integer?Positive] :=
                idx = Range @@ Sort[{m, n}];
                ReplacePart[l, Thread[idx -> l[[RotateLeft[idx, Sign[n - m]]]]]]]

Both moveElementUp[] and moveElementDown[] in his answer can be replaced with this unified function.


Probably not the most elegant way but...

swap[list_, from_, to_] := 
 Module[{ele = list[[from]], modlist = list}, 
  modlist[[from]] = Sequence[]; modlist = Insert[modlist, ele, to];

swap[list, 1, 3]

{b, c, a, d, e, f}

If you always want the moving element in front of d...

swap[list, 1, FirstPosition[list, d] - 1]

Note, in 10.2 you can use Nothing instead of Sequence[].

Or, if you insist on using patterns...

from = 1;
to = 3;
list /. {a___, list[[from]], b___, list[[to + 1]], c___} :> {a, b, 
 list[[from]], list[[to + 1]], c}

Or you could just

moveElement[l_, from_, to_] := Insert[Delete[l, from], l[[from]], to]

Works up and down.


enter image description here

list = {a, b, c, d, e, f};
SubsetMap[RotateLeft, list, {1, 2, 3}]

{b, c, a, d, e, f}

move[lst_, from_, to_] :=  Module[{a = lst, p = Sort[{from, to}]}, 
  a[[p[[1]] ;; p[[2]]]] =  RotateRight[a[[p[[1]] ;; p[[2]]]], to - from]; a]

move[{a, b, c, d, e, f}, 1, 3]

{b, c, a, d, e, f}

move[{a, b, c, d, e, f}, 3, 1]

{c, a, b, d, e, f}


Your Answer

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

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