data-structures intermediate

How to use the map function to transform array elements in Perl?

Question

How to use the map function to transform array elements in Perl?

Using map to Transform Array Elements in Perl

The map function in Perl is a powerful built-in tool used to apply a transformation or computation to each element of a list or array, returning a new list with the transformed elements. It's a classic example of Perl’s TMTOWTDI (There’s More Than One Way To Do It) philosophy, allowing concise and expressive data manipulation without explicit loops.

How map Works

The syntax of map is:

map BLOCK LIST

or equivalently:

map EXPR, LIST

For each element in LIST, map executes BLOCK or EXPR with $_ set to the current element and collects the results into a new list. Nothing in the original array is changed unless you assign the output of map back into it.

Key Concepts

  • Sigils: Remember you typically use a scalar variable $_ inside the map block representing the current list element.
  • Context: map runs in list context and always returns a list.
  • Transformation: You can perform any operation, from simple arithmetic to complex data manipulation within the block.

Basic Example

Suppose you want to transform a list of numbers by squaring each element:

#!/usr/bin/env perl
use strict;
use warnings;

my @numbers = (1, 2, 3, 4, 5);

# Use map to create a new list with each number squared
my @squares = map { $_ * $_ } @numbers;

print "Original numbers: @numbers\n";
print "Squared numbers : @squares\n";

This will output:

Original numbers: 1 2 3 4 5
Squared numbers : 1 4 9 16 25

Modifying the Original Array

Although map returns a new list, you can update the original array by assigning back:

@numbers = map { $_ * 2 } @numbers;
print "Doubled numbers: @numbers\n";

Practical Usage Tips and Gotchas

  • Don’t confuse map with grep: map transforms elements, grep filters them.
  • Beware of side effects: Since map is intended for transformation, avoid using it solely for side-effects like printing; use a for loop instead.
  • Context-sensitivity inside map: If you call functions that behave differently in scalar vs list context, be explicit.
  • Readability matters: For very complex transformations, using for loops may be clearer.

More Advanced Example: Capitalizing Strings

#!/usr/bin/env perl
use strict;
use warnings;

my @words = qw(perl python ruby javascript);

# Capitalize the first letter of each word
my @capitalized = map { ucfirst $_ } @words;

print "Original words: @words\n";
print "Capitalized  : @capitalized\n";

This illustrates how map can be used to apply almost any transformation:

  • ucfirst capitalizes the first character.
  • Could easily be swapped out for any custom code.

Summary

The Perl map function is an essential tool for functional-style list transformations, allowing you to succinctly apply operations on each element of an array and return a new list of results. By understanding how map sets $_ and returns a list, and by avoiding side-effects, you can write clear, idiomatic Perl code that embraces the "there’s more than one way to do it" philosophy.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 6ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Original numbers: 1 2 3 4 5
Squared numbers : 1 4 9 16 25
STDERR
(empty)

Was this helpful?

Related Questions