MapAt¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
MapAt[f, expr, n]
applies f to the element at position n in expr. Negative n counts from the end.
MapAt[f, expr, {i, j, ...}]
applies f to the part of expr at position {i, j, ...}.
MapAt[f, expr, {{i1, j1, ...}, {i2, j2, ...}, ...}]
applies f to the parts of expr at each of the listed positions.
MapAt[f, pos]
is the operator form: MapAt[f, pos][expr] == MapAt[f, expr, pos].
Notes
Positions take the form Position returns, and may contain All or Span specifications; 0 targets the head. On an association a position is a key, Key\[k\], or a positional index over the entries, and f is applied to the value. Repeated positions apply f repeatedly. MapAt\[f, expr, {}\] is an empty list of positions and maps nothing, while {{}} is the position of expr itself. A position that does not exist leaves MapAt unevaluated.Examples (10)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic examples (5)¶
In[1]:= MapAt[#^2 &, <|"a" -> 3, "b" -> 4|>, "b"]
Out[1]= <|"a" -> 3, "b" -> 16|>
In[2]:= p = <|"a" -> 1, "b" -> 9|>; MapAt[-# &, p, First[Position[p, 9]]]
Out[2]= <|"a" -> 1, "b" -> -9|>
In[3]:= MapAt[f, <|"a" -> 1, "b" -> 2|>, All]
Out[3]= <|"a" -> f[1], "b" -> f[2]|>
In[4]:= MapAt[f, <|"a" -> 1, "b" -> 2, "c" -> 3|>, 1 ;; 2]
Out[4]= <|"a" -> f[1], "b" -> f[2], "c" -> 3|>
In[5]:= ReplaceAt[<|"a" -> 1, "b" -> 2|>, 1 -> 9, Key["a"]]
Out[5]= <|"a" -> 9, "b" -> 2|>
Applications (5)¶
In[6]:= MapAt[f, {a, b, c, d}, 2]
Out[6]= {a, f[b], c, d}
In[7]:= MapAt[f, {a, b, c, d}, -1]
Out[7]= {a, b, c, f[d]}
In[8]:= MapAt[f, {{a, b}, {c, d}}, {2, 1}]
Out[8]= {{a, b}, {f[c], d}}
In[9]:= MapAt[f, {a, b, c, d}, {{1}, {3}}]
Out[9]= {f[a], b, f[c], d}
In[10]:= MapAt[Framed, {1, 2, 3, 4, 5}, {{1}, {-1}}]
Out[10]= {Framed[1], 2, 3, 4, Framed[5]}
Implementation notes¶
Algorithm. builtin_map_at applies f at explicit positions rather than at
levels. It first disambiguates a single position from a list of positions: the
argument is treated as multiple paths only when it is a non-empty List whose
first element is itself a List. A single path is then a position vector
{i1, i2, ...} (or a bare index), and the recursive mapat_at_path walks it:
when the path is exhausted it applies f to the targeted node
(mapat_apply_f, which builds f[node] and calls evaluate()); otherwise it
rebuilds the current EXPR_FUNCTION with the chosen child replaced by the
recursive result. A path step may be a positive/negative integer (negatives
count from the end, 0 targets the head), the symbol All (apply to every
child at that level), or a Span[a, b] / Span[a, b, step] range. Out-of-range
indices are silently ignored, a permissive convention.
For the multiple-positions form the paths are applied sequentially to a
running copy of the expression, so repeated positions apply f more than once.
Data structures. Operates on the Expr tree; copies each level's argument
array and overwrites only the targeted slot, then rebuilds with
expr_new_function.
Attributes: Protected.
References¶
See also: Position, Span, List, ReplaceAt
- Source:
src/funcprog.c - Specification:
docs/spec/builtins/data-structures.md - Tests:
tests/test_association.c - Tests:
tests/test_mapat.c
Notes & additional examples¶
Notes¶
MapAt[f, expr, n] applies f to the element at position n; negative n counts from the end and 0 targets the head. A position list like {2, 1} selects a part deep in a nested expression, while a list of positions {{1}, {3}} applies f at several places at once (last two examples). Positions may also use All or Span. Repeated positions apply f more than once at that part.