# Move element inside a list

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

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


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

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


How would I do this? Thank you!

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


or

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


Both give

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


### Edit

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}


### Note

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] :=
Module[{idx},
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];
modlist]

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.

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


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

ClearAll[move]
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}