Step 1 of 5 · Reading · ~3 min
Learn
Arrays
Transforming Arrays: map, filter, reduce
Three functions replace most of the loops you would otherwise write. Each takes an array and a callback, hands back a result, and leaves the original array untouched.
| Function | The question it answers | Gives back |
|---|---|---|
array_map | What is each element turned into? | An array of the same size |
array_filter | Which elements do I keep? | A smaller array |
array_reduce | What is the single answer for the whole array? | One value |
Chained, they read as a pipeline. Here is the exact one your exercise needs, stage by stage:
input : 1 2 3 4 5
filter even : 2 4
map square : 4 16
array_sum : 20
The argument order trap
The two functions you will use most take their arguments in opposite orders. There is no logic to it; it is history.
| ✓ Correct | |
|---|---|
array_map($callback, $array) | callback first |
array_filter($array, $callback) | array first |
Get it backwards and PHP raises a TypeError about the argument types — annoying to read, but at least it fails loudly instead of quietly.
map and filter in action
<?php
$nums = [1, 2, 3, 4, 5];
$evens = array_filter($nums, fn($n) => $n % 2 === 0);
print_r($evens);
$squares = array_map(fn($n) => $n * $n, $evens);
print_r($squares);
echo array_sum($squares), "\n";
//> Array
//> (
//> [1] => 2
//> [3] => 4
//> )
//> Array
//> (
//> [1] => 4
//> [3] => 16
//> )
//> 20
Why are the keys 1 and 3?
Because array_filter preserves the original keys. It removed elements, not positions, so the survivors keep the indexes they had. array_map then keeps whatever keys it was handed.
That is fine when you are summing or counting. It matters the moment you index the result:
| ✗ | ✓ |
|---|---|
$evens[0] — does not exist | array_values($evens)[0] |
json_encode($evens) produces an object | json_encode(array_values($evens)) produces an array |
Wrap the filter in array_values() whenever you need a clean 0-indexed list.
Called with no callback at all, array_filter simply drops every falsy element:
<?php
print_r(array_filter([0, 1, "", "0", "keep", null, []]));
//> Array
//> (
//> [1] => 1
//> [4] => keep
//> )
That is the falsy list from the conditionals lesson, doing real work.
reduce — and why array_sum exists
array_reduce($array, $callback, $initial) walks the array carrying an accumulator. The callback receives the accumulator and the current element, and returns the next accumulator.
<?php
$nums = [1, 2, 3, 4, 5];
echo array_reduce($nums, fn($acc, $n) => $acc + $n, 0), "\n";
echo array_sum($nums), "\n";
//> 15
//> 15
The third argument is not really optional. Leave it out and the accumulator starts as null, so an empty array reduces to null — which echoes as an empty line, not as 0. array_sum([]) returns a real 0, which is why it is the safer choice for totals.
Your exercise
Sum of Squares of Evens reads one line of integers and prints the sum of the squares of the even ones.
The starter parses the line into $nums; you write the pipeline — filter the evens, map each to its square, total them. The mistake the grader catches is the empty case: one hidden test feeds 1 3 5 7, where nothing at all survives the filter, and the expected output is 0. array_sum([]) gives you that for free, but a reduce without an initial value returns null there and prints a blank line. The other trap is the argument order above — array_filter takes the array first, array_map takes the callback first. Print just the total, then a newline.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…