--- name: map signatures: - 'map BLOCK LIST' - 'map EXPR, LIST' since: 5.0 status: documented categories: ["Lists"] --- ```{index} single: map; Perl built-in ``` *[Lists](../perlfunc-by-category)* # map Apply a block or expression to each element of a list and return the flattened results. `map` evaluates `BLOCK` (or `EXPR`) once per element of `LIST`, with [`$_`](../perlvar) aliased to that element, and collects everything each evaluation returns into a single flat list. Because each evaluation may yield zero, one, or many values, the output length is independent of the input length — that flattening is the point of `map`. In list context `map` returns the generated list; in scalar context it returns the total element count. ## Synopsis ```perl my @out = map { BLOCK } LIST; # block form my @out = map EXPR, LIST; # expression form my @out = map { f($_) } grep { ... } sort LIST; # chained ``` ## What you get back A single flat list built by concatenating the return values of each evaluation, in input order: - Return one value per input → transform (same length out). - Return a list per input → 1-to-N expansion (longer out). - Return the empty list `()` → skip this input (shorter out; `map`-as-filter idiom). In scalar context the return value is the count of generated elements, not a reference and not a boolean. Assigning the result to a hash is well-defined: the flat list is consumed as alternating key/value pairs. ```perl my @doubled = map { $_ * 2 } 1 .. 4; # (2, 4, 6, 8) my @words = map { split /\s+/, $_ } @lines; # 1-to-N my @kept = map { $_ > 0 ? $_ : () } @nums; # filter my $count = map { $_ * $_ } @nums; # scalar ctx ``` ## Global state [`$_`](../perlvar) is **aliased** to each element of `LIST`, not copied. Modifying [`$_`](../perlvar) inside the block modifies the source element. This is occasionally useful but usually a footgun — reach for a plain `foreach` loop when you mean to mutate in place. ```perl my @v = (1, 2, 3); my @r = map { $_ *= 10; $_ } @v; # @v is now (10, 20, 30) — the source was mutated ``` Aliasing to a non-variable (a literal, a function return value, a hash-slice element that doesn't exist yet) and then assigning to [`$_`](../perlvar) fails at runtime with `Modification of a read-only value`. See [`$_`](../perlvar). `map` also localises [`$_`](../perlvar) around the call, so an outer [`$_`](../perlvar) visible to the caller is restored when `map` returns. ## Examples Transform — uppercase every word: ```perl my @upper = map { uc } @words; ``` 1-to-N expansion — split each line on whitespace into its tokens: ```perl my @tokens = map { split /\s+/ } @lines; ``` Filter idiom — keep only truthy, transformed values: ```perl my @positives = map { $_ > 0 ? $_ : () } @numbers; ``` Build a hash from a list — each evaluation returns a two-element list: ```perl my %seen = map { $_ => 1 } @keys; my %idx = map { ($keys[$_] => $_) } 0 .. $#keys; ``` Composed pipeline — sort, filter, transform. `map`, [`grep`](grep), and [`sort`](sort) all take a `LIST` on the right, so they chain right-to-left: ```perl my @top = map { "$_->{name}: $_->{score}" } sort { $b->{score} <=> $a->{score} } grep { $_->{score} >= 50 } @records; ``` Flatten structure — each input contributes a variable number of outputs: ```perl my @leaves = map { ref($_) eq 'ARRAY' ? @$_ : $_ } @mixed; ``` Pair with index using `List::Util::pairs` or an explicit index variable — `map` itself does not expose one: ```perl my @numbered = do { my $i = 0; map { sprintf "%d. %s", ++$i, $_ } @items; }; ``` ## Edge cases - **[`$_`](../perlvar) is aliased, not copied**. Assigning to [`$_`](../perlvar) writes back to the source. If the source element is read-only (a constant, the return value of a function call flattened into `LIST`) the assignment raises `Modification of a read-only value`. Treat [`$_`](../perlvar) as input-only unless you specifically want the side effect. - **`map` is not a loop**. [`last`](last), [`next`](next), [`redo`](redo), and loop labels do not apply to `map`. They refer to the enclosing real loop and will behave accordingly — usually not what the author intended. Use `foreach` when you need loop-control flow. - **Void context is deprecated**. `map { ... } LIST;` with the result discarded emits a `Useless use of map in void context` warning under `use warnings`. When you want the side effects, not the list, write a `foreach`. - **`BLOCK` vs `EXPR` parser ambiguity**. `{` starts both a block and a hash-reference constructor. `map { ... } LIST` and `map { ... }, LIST` look identical to the parser at the opening brace; Perl guesses based on what it finds next. A block starting with what looks like a hash key plus `=>` is especially likely to be guessed wrong: ```perl my %h = map { "\L$_" => 1 } @a; # guessed EXPR, wrong my %h = map { +"\L$_" => 1 } @a; # unary + forces BLOCK my %h = map {; "\L$_" => 1 } @a; # leading ; forces BLOCK my %h = map { ($_, 1) } @a; # parens — unambiguous my %h = map { lc($_) => 1 } @a; # function call — unambiguous ``` To return an anonymous hash per element, force the hash-ref constructor with `+{`: ```perl my @hashes = map +{ lc($_) => 1 }, @array; ``` - **Order is stable**. `map` evaluates left-to-right and concatenates results left-to-right. The generated list preserves input order, with each input's contribution appearing contiguously. - **Empty `LIST`**. `map` evaluates the block zero times and returns the empty list. The block is not evaluated for its side effects. - **Nested `map`**. Inner `map` sees its own [`$_`](../perlvar); the outer [`$_`](../perlvar) is shadowed for the duration of the inner evaluation. Capture the outer value first if both are needed: ```perl my @pairs = map { my $outer = $_; map { [$outer, $_] } @inner } @outer; ``` ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`grep`](grep) — same shape as `map`, but keeps elements for which the block is true rather than transforming them; chains naturally with `map` and [`sort`](sort) - [`sort`](sort) — orders a list; commonly composed with `map` via the Schwartzian transform (`map` → [`sort`](sort) → `map`) - `for` / `foreach` — use when you want iteration for side effects, mutation of the source, or loop-control ([`last`](last)/[`next`](next)/[`redo`](redo)) - `x` — list repetition operator; orthogonal to `map` but often used to build the `LIST` that `map` consumes - [`List::Util::reduce`](../../List/Util/reduce) — fold a list to a single value; use when the result is not a list but an aggregate (sum, max, first match) - [`$_`](../perlvar) — the element alias inside the block; read-only when the source element is a literal or function return value