Array operations: array_map, array_filter, array_reduce

As a php engineer, I’m used to using arrays for everything. Arrays in php are very versatile they can work as a traditional integer-indexed array. They can work as a hashmap or associative array, using a string as an index, which can be descriptive of the value it indexes. Finally they can be multidimensional arrays, containing multiple arrays within it, that can be accessed via multiple indexes.

Integer-indexed array

This type of array can be used to store any type of element, but indexes are always integers. Indexes start at zero by default and are incrementally assigned unless explicitly used.

<?php 
  
// Indexed array:
$fruits = [‘banana’, ‘apple’, ‘peach’, ‘melon’];

// accessing array:
echo $fruits[0];
// banana
echo $fruits[1];
// apple
echo $fruits[2];
// peach
echo $fruits[3];
// melon

// Another way to initialise arrays
$otherFruits = [];
$otherFruits[0] = ‘kiwi’;
$otherFruits[1] = ‘orange’;
$otherFruits[3] = ‘pear’;

// accessing array:
echo $otherFruits[0];
// kiwi
echo $otherFruits[1];
// orange
echo $otherFruits[2];
// null
echo $otherFruits[3];
// pear

Associative array

Associative arrays differ from integer-indexed ones in the sense that associative arrays are indexed by strings. Descriptive names can be used for the information they hold.

<?php 
  
// Associative array:
$user = [
	‘name’ => ‘John Smith’,
	‘email’ => ‘john@smith.com’,
	‘address’ => ’52 York St.’
];

echo $user[‘name’];
// John Smith

Multidimensional arrays

These arrays contain other nested arrays. They can be used, for example, to hold a two-dimensional numeric matrix or a database recordset.

<?php

// letter matrix
$graph = [];

$graph[0] = [‘a’, ‘b’, ‘c’];
$graph[1] = [‘d’, ‘e’, ‘f’];
$graph[2] = [‘g’, ‘h’, ‘I’];

echo $graph[1][0]
// d

// db recordset

$users = [
    [
        ‘name’ => ‘John Smith’,
        ‘email’ => ‘john@smith.com’,
        ‘address’ => ’52 York St.’
    ],
    [
        ‘name’ => ‘Joseph Jones’,
        ‘email’ => ‘joe@jones.com’,
        ‘address’ => ’25 Victoria St.’
    ],
    [
        ‘name’ => ‘Rupert Nigels’,
        ‘email’ => ‘rupert@nigels.com’,
        ‘address’ => ’38 Stratford Ln.’
    ],
];

echo $users[1]['name'];
// Joseph Jones

php has a very rich library of very useful array functions, three of which I find particularly useful. Those are array_map, array_reduce and array_filter.

array_map

Say you have received an associative array containing a database record set, each one representing a user but what you really need is an array containing only the list of emails.

// what you have

$users = [
    [
    	'id' => 1,
        ‘name’ => ‘John Smith’,
        ‘email’ => ‘john@smith.com’,
        ‘address’ => ’52 York St.’,
        'admin' => 1
    ],
    [
	    'id' => 2,
        ‘name’ => ‘Joseph Jones’,
        ‘email’ => ‘joe@jones.com’,
        ‘address’ => ’25 Victoria St.’,
        'admin' => 0
    ],
    [
	    'id' => 3,
        ‘name’ => ‘Rupert Nigels’,
        ‘email’ => ‘rupert@nigels.com’,
        ‘address’ => ’38 Stratford Ln.’,
        'admin' => 0
    ],
];

// what you need

$emailList = [‘john@smith.com’, ‘joe@jones.com’, ‘rupert@nigels.com’];

You could achieve this by iterating over the array and filling an empty array with the email addresses:

$emailList = [];
foreach($users as $user)
{
	$emailList[] = $user['email'];
}

However, with array_map you can achieve this in a single function call. The function array_map takes an anonymous function as the first parameter and the input array as the second parameter:

$emailList = array_map(function($element){ return $element['email']; }, $users);

array_filter

If you have an array, but only need some of the elements in it, you can use the array_filter function. It takes an anonymous function as a second parameter that should return true for the element to be returned in the result array. Let's say you need the users that are admin:

$adminUsers = array_filter($users, function($element){ return $element['admin'] == 1; });

array_reduce

This function is my favourite one, it reduces the array to a single value. This return value can be pretty much anything (integer, string, etc.) and an initial value must be passed when calling array_reduce.

Let's say we need to have a string containing the names of all users, separated by commas:

$userString = array_reduce($users, function($carry, $item){ return $carry . ", " . $item['name']; }, 'Unnamed User');

// returns "Unnamed User, John Smith, Jospeh Jones, Rupert Nigels"

What's wrong with foreach?

Nothing. You can keep using foreach loops for these operations. I used to refuse to use these functions because I though my code was more readable using foreach. However, some operations are so common that it feels ridiculous to keep repeating foreach loops for them, and they are even more common if you work with data that came from an API.

Other array functions

As I said earlier, php has a very rich library of array functions. Try to replace some of your foreach loops with them where it seems to fit. Your code will be less clunky and much easier to read. Other functions I use are: array_column, array_walk, array_search, array_combine, check them out!

Show Comments