Skip to main content
replaced http://mathematica.stackexchange.com/ with https://mathematica.stackexchange.com/
Source Link
  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, f[pat] := 1 /; Sow[h -> c]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or more cleanly, though perhaps rather enigmatically, using Cases itself:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 

Finally, if traversal order is irrelevant:

Reap[expr /. pat :> 1 /; Sow[h -> c]][[2, 1]] 
{f -> x, f -> g[y], f -> z, g -> y} 

A note regarding another ramification of Alternatives is here:


NOTE: It looks like my assumptions about efficiency were wrong, and the multi-pass method may be more efficient than the rest. I need to explore this further but I have neither the time nor the interest right now.

  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, f[pat] := 1 /; Sow[h -> c]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or more cleanly, though perhaps rather enigmatically, using Cases itself:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 

Finally, if traversal order is irrelevant:

Reap[expr /. pat :> 1 /; Sow[h -> c]][[2, 1]] 
{f -> x, f -> g[y], f -> z, g -> y} 

A note regarding another ramification of Alternatives is here:


NOTE: It looks like my assumptions about efficiency were wrong, and the multi-pass method may be more efficient than the rest. I need to explore this further but I have neither the time nor the interest right now.

  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, f[pat] := 1 /; Sow[h -> c]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or more cleanly, though perhaps rather enigmatically, using Cases itself:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 

Finally, if traversal order is irrelevant:

Reap[expr /. pat :> 1 /; Sow[h -> c]][[2, 1]] 
{f -> x, f -> g[y], f -> z, g -> y} 

A note regarding another ramification of Alternatives is here:


NOTE: It looks like my assumptions about efficiency were wrong, and the multi-pass method may be more efficient than the rest. I need to explore this further but I have neither the time nor the interest right now.

deleted 30 characters in body
Source Link
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k
  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, Scan[(f[#]f[pat] := 1 /; Sow[h -> c]) &, pat];c]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or much more cleanly, though perhaps rather enigmatically, using Alternatives and Cases itself:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 

Finally, if traversal order is irrelevant:

Reap[expr /. pat :> 1 /; Sow[h -> c]][[2, 1]] 
{f -> x, f -> g[y], f -> z, g -> y} 

A note regarding another ramification of Alternatives is here:


NOTE: It looks like my assumptions about efficiency were wrong, and the multi-pass method may be more efficient than the rest. I need to explore this further but I have neither the time nor the interest right now.

  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, Scan[(f[#] := 1 /; Sow[h -> c]) &, pat]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or much more cleanly, though perhaps rather enigmatically, using Alternatives and Cases:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 

Finally, if traversal order is irrelevant:

Reap[expr /. pat :> 1 /; Sow[h -> c]][[2, 1]] 
{f -> x, f -> g[y], f -> z, g -> y} 

A note regarding another ramification of Alternatives is here:

  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, f[pat] := 1 /; Sow[h -> c]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or more cleanly, though perhaps rather enigmatically, using Cases itself:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 

Finally, if traversal order is irrelevant:

Reap[expr /. pat :> 1 /; Sow[h -> c]][[2, 1]] 
{f -> x, f -> g[y], f -> z, g -> y} 

A note regarding another ramification of Alternatives is here:


NOTE: It looks like my assumptions about efficiency were wrong, and the multi-pass method may be more efficient than the rest. I need to explore this further but I have neither the time nor the interest right now.

added 144 characters in body
Source Link
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k
  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, Scan[(f[#] := 1 /; Sow[h -> c]) &, pat]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or much more cleanly, though perhaps rather enigmatically, using Alternatives and Cases:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 

Finally, if traversal order is irrelevant:

Reap[expr /. pat :> 1 /; Sow[h -> c]][[2, 1]] 
{f -> x, f -> g[y], f -> z, g -> y} 

A note regarding another ramification of Alternatives is here:

  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, Scan[(f[#] := 1 /; Sow[h -> c]) &, pat]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or much more cleanly, though perhaps rather enigmatically, using Alternatives and Cases:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 
  • Patterns in Alternatives are tried in order
  • Only the first pattern that matches is "applied" to the expression.
  • Cases does not support multiple patterns outside of Alternatives.

I suppose it could be interesting to debate that design decision but nevertheless that's the way it works at this time.

You could of course search with multiple passes:

expr = f[x, g[y], z] pat = h_[c_] | h_[c_, __] | h_[__, c_, __] | h_[__, c_]; Join @@ (Cases[expr, # :> h -> c, {0, -1}] & /@ List @@ pat) 
{g -> y, f -> x, f -> g[y], f -> z} 

Or using ReplaceList and Level:

rules = # :> h -> c & /@ List @@ pat Join @@ (ReplaceList[#, rules] & /@ Level[expr, {0, -1}]) 

Since neither of these is efficient you could subvert the normal evaluation by using side-effects, e.g. with Condition:

Module[{f}, Scan[(f[#] := 1 /; Sow[h -> c]) &, pat]; Reap[Scan[f, expr, {0, -1}]][[2, 1]] ] 
{g -> y, f -> x, f -> g[y], f -> z} 

Or much more cleanly, though perhaps rather enigmatically, using Alternatives and Cases:

Reap[Cases[expr, pat :> 1 /; Sow[h -> c], {0, -1}];][[2, 1]] 
{g -> y, f -> x, f -> g[y], f -> z} 

Finally, if traversal order is irrelevant:

Reap[expr /. pat :> 1 /; Sow[h -> c]][[2, 1]] 
{f -> x, f -> g[y], f -> z, g -> y} 

A note regarding another ramification of Alternatives is here:

added 288 characters in body
Source Link
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k
Loading
Source Link
Mr.Wizard
  • 275.2k
  • 34
  • 606
  • 1.5k
Loading