1
$\begingroup$

I have a variable g, indexed by a list:

g[{1,1}]=11;
g[{1,2}]=12;
g[{2,1}]=21;
g[{2,2}]=22;

I would like to move things around as follows:

g[{1,1}]=g[{2,1}];
g[{1,2}]=g[{2,2}];

but using

L1={{1,1},{1,2}};
L2={{2,1},{2,2}};

I tried Map[g,L1]=Map[g,L2] but that's not right. Is there a concise way of doing this?

$\endgroup$

1 Answer 1

1
$\begingroup$

You can use MapThread:

MapThread[(g[#] = g[#2]) &, {L1, L2}]
(* {21, 22} *)

?g
(*
Global`g
g[{1,1}]=21
g[{1,2}]=22
g[{2,1}]=21
g[{2,2}]=22
*)

If you want to do everything in one go (e.g. if you want to swap elements), you can use the following approach:

(# = Map[g, L2]) &@Map[g, Unevaluated@# &@L1, {2}];

?g
(* same result *)

As you can see, this approach requires some careful evaluation control:

  • In the end, we need {g[…],g[…]} on the left side of the assignment
  • To do this, we want to pass Unevaluated[{g[…],g[…]] to the function (# = …)&.
  • We have to map g over the list after we wrapped it in Unevaluated, otherwise it will just evaluate
  • We need to force L1 to be evaluated inside Unevaluated, hence the Unevaluated@#&@L1

Using ReplaceAll, it is a bit easier to build the final expression:

g /@ Hold @@ L1 /. Hold[lhs___] :> ({lhs} = Map[g, L2]);

?g
(* same result *)

Here, we build an expression of the form Hold[g[…], g[…]], and then insert it into the assignment using ReplaceAll.

$\endgroup$

Your Answer

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

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