8

Two different examples of same problem:

In: Cases[{f^2, g^3, k^p, h}, x_^n_ -> n]

Out: {2,3,p} # The result misses the exponen of h, '1'

The same problem in a different context:

In: Cases[{f[a],2 f[b]}, f[x_] -> x]

Out: {a} # result misses b. A "fix" could be

Cases[{f[a],2 f[b]}, Real_ f[x_] -> x]

Out: {b} # now it misses 'a' !!

Can this be solved, without resorting to Union of lists?

Rohit Namjoshi
  • 10,212
  • 6
  • 16
  • 67
MaxB
  • 311
  • 1
  • 5
  • Hey MaxB! You might have a better response if you format your question's code in a way that makes it easier for others to help answer :D Look's like Rohit helped you out with this one :) – CA Trevillian May 15 '20 at 18:48
  • 6
    Pattern matching in Mathematica can sometimes be a bit surprising since the code the patterns search is not the same as what you see on the screen. In particular, you may be surprised by the output of FullForm[1/Sqrt[2]] if you ever need to pattern match square roots. Using FullForm[{f^2, g^3, k^p, h}] and FullForm[{f[a], 2 f[b]}] will allow you to see what Mathematica sees when it's searching through the expressions. In the first example, you can see that they all have Power except for the last one. – MassDefect May 15 '20 at 19:05

1 Answers1

11

You can find them all using

  Cases[{f^2, g^3, k^p, h}, x_^n_. :> n]

Mathematica graphics

Same for the other one

 Cases[{f[a], 2 f[b]}, any_. f[x_] :> x]

 (* {a, b} *)

Or for the above second example, you do not have to name it any or any other name since you are not using it, so you can also just do

  Cases[{f[a], 2 f[b]},  _.  f[x_] :> x]
  (* {a, b} *)

The rules are

Mathematica graphics

Notice that it says x_^n_ does not match 1 for n. Same thing for the second example.

I also changed -> to :>. It is more safe this way. The rule of thumb for this, if x_ or n_ or whatever named pattern is used, shows up on left side then more safe to use :> to emit it on right side of the rule.

Learned this rule from Power Programming with Mathematica: The Kernel Book by David B. Wagner page 148, where he gives an example of why this can make difference if delayed version is used or not.

ClearAll[u, y];
expr = Sqrt[u - 1]/Sqrt[u^2 - 1];
expr /. 1/Sqrt[y_] -> 1/Sqrt[Factor[y]]

Mathematica graphics

Compare to what happens when using :> instead of ->

 expr /. 1/Sqrt[y_] :>  1/Sqrt[Factor[y]]

Mathematica graphics

Which is what we wanted. Wagner gives the explanation of the difference as follows

Mathematica graphics

So when in doubt, or if something does not happen the way you expect it, use :> instead of ->. In your examples, using -> or :> gives same result, since this issue does not show up. But in more complicated cases it can as in the example in the book above.


Here is summary of most important rules from my Mathematica cheat sheet collected from Wolfram help pages

Mathematica graphics

Nasser
  • 143,286
  • 11
  • 154
  • 359
  • 3
    Fantastic! I knew there had to be a way but could find it myself. Thank you ! – MaxB May 15 '20 at 19:09
  • Hey @Nasser, it seems that the any_. syntax is more robust than just the Power example, as you show, can you point to a good resource on why this works? I didn't know about this! Very cool. – CA Trevillian May 15 '20 at 19:12
  • 1
    @CATrevillian most of these are given in different help pages. Please see tutorial/Patterns as an example. – Nasser May 15 '20 at 19:34
  • 2
    @CATrevillian The head of any_. is Optional – Michael E2 May 15 '20 at 19:35
  • 1
    @MichaelE2 and Nasser, thanks to both of you for the clarification! Seems here is specifically where I should look. Even still, it is quite new to me, and I wonder if one can define the default values as one sees fit! I know of the ability to define optional and default arguments in a function, but the _. syntax is new to and not yet understood by me. Thanks also for the additional additional clarifications to your answer, Nasser! – CA Trevillian May 15 '20 at 19:52
  • 1
    "I wonder if one can define the default values as one sees fit!" - @CA, look up Default[] for this. – J. M.'s missing motivation May 16 '20 at 04:44