6.3 Map

The function map applies an expression on each element of an array. It has a hidden loop and all array elements are assigned to the special variable $_. Map returns a new array with the results. I prefer the block syntax with curly braces:

@array_new = map {...} @array

Example 1a: uppercase all elements with $_


@arr = qw( a b c );
@arr_new = map { uc($_) } @arr; 
print("@arr_new"); # output: A B C
The special variable $_ can be left out:

Example 1b: uppercase all elements without $_

@arr = qw( a b c );
@arr_new = map { uc } @arr; # $_ is left out
print("@arr_new"); # output: A B C
Conditionals can -of course- be applied within a block:

Example 1c: some comparison

@arr = qw( A b C );
@arr_new = map { ($_ eq 'b') ? uc : lc } @arr;
print("@arr_new"); # output: a B c
Example 2a: increment all elements (array)

@arr = qw( 1 2 3 );
@arr_new = map { $_ + 10 } @arr; 
print("@arr_new"); # output: 11 12 13
Example 2b: increment all elements (range)

@arr = map { $_ + 10 } 1..3;
print("@arr"); # output: 11 12 13
Example 3: increment all elements differently

$count = 1;
@arr = map { $_ + ($count++) } (50,60,70);
print("@arr"); # output: 51 62 73
Example 4: ternary operator

@arr = map { ($_ % 2) ? $_ : ($_ * 2) } (2..10);
print("@arr"); # output: 4 3 8 5 12 7 16 9 20
Example 5: change $_ = change original array

@arr = qw( 1 2 3 );
@arr_new = map { $_ += 10 } @arr; # here is $_ changed, i.e. the original array will be modified also
print("old: @arr and new: @arr_new"); # output: old: 11 12 13 and new: 11 12 13
Example 6:

@arr = qw( prefixA prefixB prefixC );
@letters = map { 
                 substr($_, 0, 6) = ""; # remove 6 characters from the beginning = 'prefix'
                 $_ = lc($_);
               } @arr;  
print("@letters"); # output: a b c as is also the contents of the original @arr
Example 7: split lines into separate array elements

@lines = ("Some are born great", "some achieve greatness", "and some have greatness thrust upon them.");
@arr = map { split(/ /, $_); } @lines;
print("$arr[1]"); # output: 'are'
Example 8:

@colors = qw(red blue green);
%colorname_length = map { $_ => (length($_)) } @colors;

foreach $color (keys(%colorname_length)) {
  print("'$color' has $colorname_length{$color} characters\n");
}
Output:

'blue' has 4 characters 'red' has 3 characters 'green' has 5 characters

Example 9:

the next example prints a 0 if $_ is even; otherwise 1
print(join(" ", (map { $_ & 1 } 1.. 5))); # output: 1 0 1 0 1

some background on bit operation AND incase of '$_ & 1'

The AND rule in a bit operation: 1 if both are 1, otherwise 0

1 & 1: 0001
       0001
       ----
       0001 -> 1 or TRUE

2 & 1: 0010
       0001
       ----
       0000 -> 0 or FALSE

3 & 1: 0011
       0001
       ----
       0001 -> 1 or TRUE

Example 10a:

print map { $x = !$x; if ($x) {$_;} else {"\t$_\n";}  } 0 .. 10; 
Output:

0	1
2	3
4	5
6	7
8	9
10
Nice trick here: $x has at the beginning the value undef, !$x makes the value 1 (true). Then: $x has the value 1 and !$x makes the value 0 (false) etc.. The following is an alternative with the ternary operator.

Example 10b:

print map { $x = !$x; ($x) ? ($_) : ("\t$_\n")  } 0 .. 10;