For example, I want to change expr1 into expr2. I am pretty sure I can do this using nested loops to find and then modify terms with subscripts, but that is clunky, old school thinking. Is there a better way? "e" in my example below is a symbol (undefined).

enter image description here

(2 + Subscript[e, 2, 1] - Subscript[e, 3, 4, 5, 1, 2]) /. 
     Subscript[z1_, z2__] :> Subscript[z1, Sequence @@ Sort[List[z2]]]

(* 2 + Subscript[e, 1, 2] - Subscript[e, 1, 2, 3, 4, 5] *)

is one option.

  • $\begingroup$ This is exactly the kind of solution I am looking for. Thank you so much. Now I'll try to digest how it works. I expect it will take me longer to digest it than it took you to produce it. $\endgroup$ – matrixbud Sep 30 '16 at 2:30
  • $\begingroup$ I pretty much understand what you did and it is a very logical approach. I don't understand why a delayed rule rather than just a rule is needed, although I see that just a rule doesn't work at all. Is it difficult for you to explain what the delay does? $\endgroup$ – matrixbud Sep 30 '16 at 3:55
  • $\begingroup$ @matrixbud Consider these simple cases. Subscript[e, 2, 1] /. Subscript[_, z2__] -> List[z2] gives {2, 1} for Rule or RuleDelayed, as it should. However, Subscript[e, 2, 1] /. Subscript[_, z2__] -> Sort[List[z2]] does not Sort, although RuldDelayed does. This is because the normal rule does the Sort on List[z2] before z2 is replaced by 2, 1. But, RuleDelayed does not do the Sort until after z2 is replaced by 2, 1. I hope this helps. $\endgroup$ – bbgodfrey Sep 30 '16 at 4:26
  • $\begingroup$ Yes, that makes a lot of sense. To confirm that I understand how this works, I surmise that "List" is also delayed until after z2 is replaced, although that has no effect one way or the other on the final answer. That is, a delayed rule makes the direct substitution occur first and then all the subsequent operations (List and then Sort) happen after that. $\endgroup$ – matrixbud Sep 30 '16 at 14:53
  • $\begingroup$ @matrixbud That is correct. f[2, 1] /. f[z__] -> {z} and f[2, 1] /. f[z__] :> {z} both give {{2, 1}, because delaying evaluation makes no difference. However, f[2, 1] /. f[z__] -> Sort[{z}] tries to Sort too soon and gives {2, 1}, while f[2, 1] /. f[z__] :> Sort[{z}] gives {1, 2}. $\endgroup$ – bbgodfrey Sep 30 '16 at 15:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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