Function Repository Resource:

MapSlice

Source Notebook

Provide the part specifications to a mapped function as a sequence of arguments after the first one

Contributed by: Seth J. Chandler

ResourceFunction["MapSlice"][f,expr]

applies f to the elements of expr, giving the sequence of part specifications of each element as the remaining argument(s) to f.

ResourceFunction["MapSlice"][f,expr,levelspec]

applies f to all parts of expr on levels specified by levelspec, with these part indices provided as the remaining arguments to f.

ResourceFunction["MapSlice"][f]

represents an operator form of ResourceFunction["MapSlice"] that can be applied to an expression at its first level.

Details and Options

ResourceFunction["MapSlice"] is a variant of MapIndexed that gives the part specifications as a sequence of arguments rather than a single List argument.
ResourceFunction["MapSlice"] uses standard level specifications just like MapIndexed.
The default value for levelspec in ResourceFunction["MapSlice"] 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.
ResourceFunction["MapSlice"] traverses the parts of expr in a depth-first order, with leaves visited before roots. 
ResourceFunction["MapSlice"] always effectively constructs a complete new expression and then evaluates it.
ResourceFunction["MapSlice"] works on SparseArray objects, effectively by applying Normal to them.
ResourceFunction["MapSlice"] works on Association objects, giving part specifications in the form Key[k].
ResourceFunction["MapSlice"][f][expr] is equivalent to ResourceFunction["MapSlice"][f,expr,{1}].

Examples

Basic Examples (5) 

Apply f to a list with four parts:

In[1]:=
ResourceFunction["MapSlice"][f, {a, b, c, d}]
Out[1]=

Argument #2 gives the index of each part:

In[2]:=
ResourceFunction["MapSlice"][#2 + f[#1] &, {a, b, c, d}]
Out[2]=

Changing the level specification affects the output:

In[3]:=
(* Evaluate this cell to get the example input *) CloudGet["https://www.wolframcloud.com/obj/76e9e5af-6426-46a7-8c4b-5bea43b660be"]
Out[3]=

Use the operator form of MapSlice:

In[4]:=
ResourceFunction["MapSlice"][f][{a, b, c, d}]
Out[4]=

Use MapSlice with an association:

In[5]:=
ResourceFunction["MapSlice"][
 Association["id" -> #2, #] &, {<|"class" -> "1st", "age" -> 29, "sex" -> "female", "survived" -> True|>, <|"class" -> "2nd", "age" -> 1, "sex" -> "male", "survived" -> True|>, <|"class" -> "1st", "age" -> 23, "sex" -> "female", "survived" -> False|>}]
Out[5]=

Scope (5) 

Functions used inside MapSlice may contain slot values as high as one more than the level specification:

In[6]:=
ResourceFunction[
 "MapSlice"][#1 + 2 #2 + 3 #3 &, {{a, b}, {c, d}}, {2}]
Out[6]=

Map onto all the elements of an expression:

In[7]:=
ResourceFunction["MapSlice"][f, {{a, b}, {c, d, {e}}}, Infinity]
Out[7]=

Map only onto the "leaves" of the expression:

In[8]:=
ResourceFunction["MapSlice"][f, {{a, b}, {c, d, {e}}}, {-1}]
Out[8]=

Map on levels 0 through 1; the head has index {}:

In[9]:=
ResourceFunction["MapSlice"][f, {a, b}, {0, 1}]
Out[9]=

MapSlice can be used on expressions with any head:

In[10]:=
ResourceFunction["MapSlice"][Times, a + b + c + d]
Out[10]=

Applications (3) 

Label parts by position:

In[11]:=
ResourceFunction["MapSlice"][Labeled, {x^2, x + y, y^2, y^3}]
Out[11]=
In[12]:=
ResourceFunction["MapSlice"][
 Framed[Labeled[#1, #2]] &, {x^2, x + y, y^2, y^3}, Infinity]
Out[12]=

Rotate lists based on position:

In[13]:=
ResourceFunction["MapSlice"][RotateLeft, Table[{a, b, c}, {6}]]
Out[13]=

Show where various elements of a three-dimensional array might be stored in memory:

In[14]:=
NumberLinePlot[
 ResourceFunction["MapSlice"][
  Tooltip[FromDigits[{##2} - 1, MixedRadix[{2, 3, 2}]], #1] &, Array[x, {2, 3, 2}], {3}], PlotLegends -> {"first row", "second row"}, AxesLabel -> {"memory offset"}]
Out[14]=

Properties and Relations (1) 

You can emulate MapIndexed using MapSlice:

In[15]:=
ResourceFunction["MapSlice"][
 f[#1, List[##2]] &, {{a, b}, {c, d}}, {2}]
Out[15]=

Possible Issues

There is no Heads option to MapSlice as there is for MapIndexed.

Neat Examples (1) 

The following two pieces of code are equivalent, but the version with MapSlice is arguably cleaner because there is no need for a Part function within the first argument; this will often be the case for functions that map at level 1:

In[16]:=
{ResourceFunction["MapSlice"][{#2, #1} &, CharacterRange["a", "i"]], MapIndexed[{Part[#2, 1], #1} &, CharacterRange["a", "i"]]}
Out[16]=

Publisher

Seth J. Chandler

Version History

  • 1.0.0 – 15 July 2019

Related Resources

License Information