Wolfram Research

MapCases

Contributed by: Richard Hennigan (Wolfram Research)

Source Notebook

Map a function at parts of an expression that match a given pattern

ResourceFunction["MapCases"][f,{e1,e2,},pattern]

applies f to each ei that matches pattern.

ResourceFunction["MapCases"][f,expr,pattern,levelspec]

applies at levels specified by levelspec.

ResourceFunction["MapCases"][f,pattern]

represents an operator form of ResourceFunction["MapCases"] that can be applied to an expression.

Details and Options

The expr can have any head, not just List.
ResourceFunction["MapCases"][f,pattern][expr] is equivalent to ResourceFunction["MapCases"][f,expr,pattern].
When used on an Association, ResourceFunction["MapCases"] matches elements according to their values.
ResourceFunction["MapCases"] uses standard level specifications:
n levels 1 through n
Infinity levels 1 through Infinity
{ n } level n only
{ n 1 , n 2 } levels n1 through n2
The default value for levelspec in ResourceFunction["MapCases"] is {1}.
A positive level n consists of all parts of expr specified by n indices.
A negative level -n consists of all parts of expr with depth n.
Level -1 consists of numbers, symbols, and other objects that do not have subparts.
Level 0 corresponds to the whole expression.
With the option setting Heads -> True, ResourceFunction["MapCases"] looks at heads of expressions, and their parts.
ResourceFunction["MapCases"] traverses the parts of expr in a depth-first order, with leaves visited before roots.
MapCases has the following options:
Heads False whether to check heads of subexpressions
EvaluateCases False whether to evaluate f[ei] inside held expressions

Examples

Basic Examples

Map a function at integers only:

In[1]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, {1, 1, g[a], 2, 3, y, g[8], 9, g[10]}, _Integer]
Out[1]=

Map a function at anything other than integers:

In[2]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, {1, 1, g[a], 2, 3, y, g[8], 9, g[10]}, Except[_Integer]]
Out[2]=

Use the operator form of MapCases:

In[3]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, _Integer]
Out[3]=
In[4]:=
%[{1, 1, g[a], 2, 3, y, g[8], 9, g[10]}]
Out[4]=

Map at matching elements in an Association:

In[5]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, <|1 -> "a", 2 -> "b", 3 -> c, 4 -> d|>, _Symbol]
Out[5]=

Scope

Apply a function to strings only:

In[6]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][StringLength, {1, 2, "a", x, "testing"}, _String]
Out[6]=

Apply a function to cases of lists of integers:

In[7]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][Total, {{1, 2}, {x}, {3, 4, 1}, "Hello", a, b}, {__Integer}]
Out[7]=

Apply a function to nonzero values only:

In[8]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][
 1/# &, {1, 0, Sqrt[2], -10, 3, Pi, 5, 0, x}, Except[0]]
Out[8]=

Apply a function to cases of lists of integers at any level:

In[9]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][Total, {g[{1, 2}], {x}, {{3, 4}, {5, 6}}, "Hello", a, {b, 2}}, {__Integer}, Infinity]
Out[9]=

Options

Heads

Map at symbols among the elements of an expression:

In[10]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, {a, 5, \[Pi]}, _Symbol]
Out[10]=

Also include the head of the expression in the search:

In[11]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, {a, 5, \[Pi]}, _Symbol, Heads -> True]
Out[11]=

EvaluateCases

By default, the f[ei] will remain unevaluated if the ei is found within a held expression:

In[12]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][Minus, Hold[1 + 1, 2*2, 3 + 3], _Plus]
Out[12]=

Evaluate each of the f[ei] when applying:

In[13]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][Minus, Hold[1 + 1, 2*2, 3 + 3], _Plus, "EvaluateCases" -> True]
Out[13]=

Applications

Convert all symbols in an expression to strings:

In[14]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][
 ResourceFunction["FullSymbolName"], {1, 1 + x, f[a], 2, 3, y, f[8], 9, f[10]}, _Symbol, Infinity]
Out[14]=

Include heads:

In[15]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][
 ResourceFunction["FullSymbolName"], {1, 1 + x, f[a], 2, 3, y, f[8], 9, f[10]}, _Symbol, Infinity, Heads -> True]
Out[15]=

Properties and Relations

MapCases[f,expr,_] is equivalent to Map[f,expr]:

In[16]:=
expr = {1, 1 + x, g[a], 2, 3, y, g[8], 9, g[10]}
Out[16]=
In[17]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, expr, _]
Out[17]=
In[18]:=
Map[f, expr]
Out[18]=

MapCases[f,expr,pattern,levelspec] is equivalent to Replace[expr,e:patternf[e],levelspec]:

In[19]:=
expr = {1, 1 + x, g[a], 2, 3, y, g[8], 9, g[10]}
Out[19]=
In[20]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, expr, _Integer, {1}]
Out[20]=
In[21]:=
Replace[expr, e : _Integer :> f[e], {1}]
Out[21]=

MapCases[f,expr,pattern,levelspec] is equivalent to MapAt[f,expr,Position[expr,pattern,levelspec]]:

In[22]:=
expr = {1, 1 + x, g[a], 2, 3, y, g[8], 9, g[10]}
Out[22]=
In[23]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, expr, _Integer, {1}]
Out[23]=
In[24]:=
MapAt[f, expr, Position[expr, _Integer, {1}]]
Out[24]=

When using the option "EvaluateCases"True, these equivalencies no longer necessarily hold:

In[25]:=
expr = Hold[1 + 1, 2*2, 3 + 3]
Out[25]=
In[26]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][Minus, expr, _, "EvaluateCases" -> True]
Out[26]=
In[27]:=
Map[Minus, expr]
Out[27]=
In[28]:=
ResourceFunction[
 "0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][Minus, expr, _Plus, {1}, "EvaluateCases" -> True]
Out[28]=
In[29]:=
Replace[expr, e : _Plus :> Minus[e], {1}]
Out[29]=

Possible Issues

MapCases by default starts at level 1, so it does not apply the function to the whole expression:

In[30]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, h1[h2[h3[x]]], _, -1]
Out[30]=
In[31]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][f, h1[h2[h3[x]]], _, {0, -1}]
Out[31]=

In MapCases[f,expr,pattern], the pattern will evaluate before matching unless wrapped in HoldPattern:

In[32]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][Minus, Hold[1 1, 2 2, 3 3, 4 1], 1*_, "EvaluateCases" -> True]
Out[32]=
In[33]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][Minus, Hold[1 1, 2 2, 3 3, 4 1], HoldPattern[1*_], "EvaluateCases" -> True]
Out[33]=

Neat Examples

Highlight integers in an expression:

In[34]:=
Integrate[1/(x^3 - 1), x]
Out[34]=
In[35]:=
ResourceFunction["0b48e8d5-3ef0-452d-8cf4-6f8cafc53812"][
 Style[#, Background -> Green] &, %, _Integer, Infinity]
Out[35]=

Resource History

See Also