Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Recently, I have being using Mathematica to write my undergraduate paper. I want to use two pattern lists such as { A -> a, B -> b, c -> C, ....} and { a -> A, b -> B, c -> C, ....} to make my code short. I can exchange { A -> a, B -> b, c -> C, ....}'s elements to achieve { a -> A, b -> B, c -> C, ....}, my trail is as below:

firstPattern = { A -> a, B -> b, c -> C, one -> two, tom -> david};

To achieve { a -> A, b -> B, C -> c, two -> one, david -> tom}, I write the code:

{#1, #2} -> {#2, #1}& /@ firstPattern

However, it failed. I wonder why and how to correct it.

share|improve this question
1  
Is this what you intend? {#[[1]], #[[2]]} -> {#[[2]], #[[1]]} & /@ firstPattern –  bill s May 2 at 5:15
    
@bills,+1,OK,thanks sincerely,I achieve the right result –  tangshutao May 2 at 5:21
2  
It doesn't get simpler than Reverse /@ firstPattern :) –  rm -rf May 2 at 5:26
    
Somewhat related: (1302) –  Mr.Wizard May 2 at 5:34

3 Answers 3

up vote 7 down vote accepted

Because life is more fun with infix:

firstPattern ~Reverse~ 2
{a -> A, b -> B, C -> c, two -> one, david -> tom}

(The serious point of this answer is that you can use the second parameter of Reverse to determine exactly what levels of the expression you wish to reverse.)

Also quite direct and terse:

#2 -> # & @@@ firstPattern
{a -> A, b -> B, C -> c, two -> one, david -> tom}

This works where your attempt doesn't by using Apply at level one, which has the shorthand @@@. This lets you access the parts of the rules rather than the entire rules themselves.


Timings

Timings, conducted in version 7, for various methods posted so far.

timeAvg = 
  Function[func,
    Do[If[# > 0.3, Return[#/5^i]] & @@ Timing@Do[func, {5^i}], {i, 0, 15}],
    HoldFirst];

rules = Rule @@@ RandomInteger[999, {500000, 2}];

Reverse /@ rules     // timeAvg
Reverse[rules, 2]    // timeAvg
#2 -> # & @@@ rules  // timeAvg
rules[[All, {2, 1}]] // timeAvg
0.1934

0.1342

0.259

0.1902

In an attempt to make this answer more worthy of the Accept I'd like to arbitrarily address an edge case that might come up. Suppose you have RuleDelayed expressions and you wish to reverse them:

rules = {a :> 1 + 1, b :> 2 + 2, c :> 3 + 3};
rules ~Reverse~ 2
{2 :> a, 4 :> b, 6 :> c}

Note that e.g. 1 + 1 became 2; for the sake of the illustration let's consider this unacceptable. Then we would need to wrap the left-hand-side in HoldPattern. A direct attempt using @@@ fails because the anonymous Function does not hold its arguments (by default):

HoldPattern[#2] -> # & @@@ rules
{HoldPattern[2] -> a, HoldPattern[4] -> b, HoldPattern[6] -> c}

One could add a HoldAll Attribute to the function but usually replacement patterns are simpler:

Replace[rules, (L_ :> R_) :> (HoldPattern[R] :> L), 1]
{HoldPattern[1 + 1] :> a, HoldPattern[2 + 2] :> b, HoldPattern[3 + 3] :> c}

Such rules may seem pointless but they can be useful for manipulating held expressions.

share|improve this answer
    
@Mr.Wizard.Perfect! –  tangshutao May 2 at 5:34

I always go with Part before attempting anything else:

firstPattern[[All, {2, 1}]]

To me at least it seems far simpler and more intuitive than many other approaches.

share|improve this answer
    
Great! For anyone wondering how/why this works see: Head and everything except Head? –  Mr.Wizard May 2 at 6:11
    
Very neat! Never thought about this one! –  sebhofer May 2 at 8:43

It doesn't get simpler than

Reverse /@ firstPattern

While Reverse is often used only on lists, it acts with any head, so Reverse@Rule[a, b] is Rule[b, a].

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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