Swap two entries in a matrix

Is there a nice, simple script one can use to swap two entires in a matrix? For example, suppose we have the matrix below:

$A=\begin{pmatrix}2 & 4 & 1\\ 3 & 1 & 2\\ 4 & 3 & 1 \end{pmatrix}$

Is there a script of the form switch[A,a,b], which will swap all occurrences of $a$ in the matrix with $b$, and vice versa, and then update the matrix $A$ accordingly? So in this case the output of switch[A,2,3] would be:

$A=\begin{pmatrix}3 & 4 & 1\\ 2 & 1 & 3\\ 4 & 2 & 1 \end{pmatrix}$

My own solution involves a lot of If and For functions, and will, I think, also run into the problems detailed here. I think it will work eventually (and I'd be happy to post what I have so far if people would like), but really I'm just wondering whether there's a simpler way to do this.

Thanks!

-

A minor point regarding ReplaceAll: ReplaceAll does not change the matrix a, so you do need to set a= (a/. {replacement rules}) or a=ReplaceAll[a,{replacement rules}].

 a = {{2, 4, 1}, {3, 1, 2}, {4, 3, 1}};
a = (a /. {2 -> 3, 3 -> 2});
a // MatrixForm


Another alternative is to use Replace at level 2:

 a = Replace[a, {2 -> 3, 3 -> 2}, {2}]


or at level -1:

 a = Replace[a, {2 -> 3, 3 -> 2}, {-1}]


Yet another alternative:

 a = Cases[a, {x___, aa : (3 | 2), y___} :> {x, If[aa == 3, 2, 3], y}, {1,Infinity}]


Update: functions to swap a pair of elements of a matrix:

ClearAll[swap];
SetAttributes[swap, HoldFirst];
swap[mat_, elem1_, elem2_] := (mat = mat /. {elem1 -> elem2, elem2 -> elem1})
swap[a,2,3]
(* {{3, 4, 1}, {2, 1, 3}, {4, 2, 1}} *)


Swap multiple pairs of elements:

ClearAll[swap2];
SetAttributes[swap2, HoldFirst];
swap2[mat_, pairs:{{_, _} ..}] := (mat = mat /.(Rule @@@ Join[pairs, Reverse /@ pairs]))
swap2[a,{{2,3}}]
(* {{2, 4, 1}, {3, 1, 2}, {4, 3, 1}}  *)
swap2[a,{{2,3},{1,4}}]
(* {{3, 1, 4}, {2, 4, 3}, {1, 2, 4}} *)


For large matrices and many pairs to swap:

ClearAll[swap3];
SetAttributes[swap3, HoldFirst];
swap3[mat_, pairs : {{_, _} ..}] :=  With[{dispatch = Dispatch[Rule @@@ Join[pairs, Reverse /@ pairs]]}, mat = (mat /. dispatch)]

-
Another way to generate the replacement rules: Dispatch[Apply[Join, Thread[# -> Reverse[#]] & /@ pairs]]. – J. M. Aug 26 '12 at 11:21
@J.M. really nice. More concise than everything I have tried. – kglr Aug 26 '12 at 12:33
@kguler Won't it be better if the swap function do not replace the original matrix itself? (I mean, if both a and swapped a are needed.) – Noble P. Abraham Aug 26 '12 at 13:24
@Noble P. Abraham That's probably because I asked for the original matrix to be replaced in my question. – Jimeree Aug 26 '12 at 13:36
@NobleP.Abraham, I agree with you. To get a version that does not replace the input matrix, one can remove the part mat= in the definition of swap and use a=swap[a,...] when one needs to replace a. – kglr Aug 26 '12 at 13:53

ReplaceAll should do it:

{{2, 4, 1}, {3, 1, 2}, {4, 3, 1}} /. {2 -> 3, 3 -> 2}

-

I like the above ReplaceAll solution the most. But to make sure there are at least 10 different ways to do something in Mathematica, here is another way

mat = {{2, 4, 1}, {3, 1, 2}, {4, 3, 1}};
pos1 = Position[mat, 2];
pos2 = Position[mat, 3];
mat = ReplacePart[mat, pos1 -> 3];
mat = ReplacePart[mat, pos2 -> 2]

-

With ReplacePart and Position:

a = {{2, 4, 1}, {3, 1, 2}, {4, 3, 1}};
ReplacePart[a, {Position[a, 2] -> 3, Position[a, 3] -> 2}]

(* {{3, 4, 1}, {2, 1, 3}, {4, 2, 1}} *)

-