Simplify your loops with array_column

Author: Stuart Maynes

The purpose of this post is to demonstrate how you can use array_column in PHP to simplify your loops and in turn your code. Using array_column reduces the number of lines of code you have to write, and the complexity of your code, which can only be a good thing.

Setting the stage

We have taken our data from the wonderful world of theatre. Below is a multidimensional array – in other words, an array of arrays. For array_column to work you either need an array of arrays, or an array of objects.

$events = [
    [
        "ID"    => "101602",
        "title" => "A Midsummer Night's Dream",
        "venue" => "Top Theatre",
        "date"  => "2020-10-10 19:30",
    ],
    [
        "ID"    => "114601",
        "title" => "The Cane",
        "venue" => "Back Theatre",
        "date"  => "2020-10-11 19:30",
    ],
    [
        "ID"    => "114801",
        "title" => "Madam Butterfly",
        "venue" => "Front Theatre",
        "date"  => "2020-10-12 19:30",
    ],
    [
        "ID"    => "105401",
        "title" => "Swan Lake",
        "venue" => "Front Theatre",
        "date"  => "2020-10-13 19:30",
    ],
];

A quick example

Given that you want to end up with an array of event IDs, a pattern that is often seen in PHP to achieve this would be to use a foreach loop.

# Array to store the IDs in
$eventIDs = [];
# Loop through each $event one at a time
foreach ($events as $event) {
    # Check to see if the ID attribute is set
    if (isset($event["ID"])) {
        # An the ID of the event onto the end of the array
        $eventIDs[] = $event["ID"];
    }
}

All of the above can be simplified down to one line by using array_column.

$eventIDs = array_column($events, "ID");
// The result will be
[
    0 => "101602",
    1 => "114601", 
    2 => "114801",
    3 => "105401"
]

Function description

array_column(array $input, mixed $column [mixed $index = null]): array

array_column() returns the values from a single column from the $input array, identified by the $column variable. The $column can either be a string or an integer. An optional third param may be provided to index the values in the returned array.

Further examples

$eventNames = array_column($events, "title");
// The result will be
[
    0 => "A Midsummer Night's Dream",
    1 => "The Cane", 
    2 => "Madam Butterfly",
    3 => "Swan Lake"
]

Specifying the index

Indexing the array using the event ID can be done by specifying the third parameter as ID.

$eventNames = array_column($events, "title", "ID");
// The result will be
[
    101602 => "A Midsummer Night's Dream", 
    114601 => "The Cane", 
    114801 => "Madam Butterfly", 
    105401 => "Swan Lake",
]

Note that the index taken from ID became an integer but was in the original array as a string.

Obtaining the complete array or object

Indexing the array using the event ID but returning the full array, this time by giving null as the second parameter.

$eventsByID = array_column($events, null, "ID");
// The result will be
[
    101602 => [
        "ID"    => "101602",
        "title" => "A Midsummer Night's Dream",
        "venue" => "Top Theatre",
        "date"  => "2020-10-10 19:30",
    ],
    114601 => [
        "ID"    => "114601",
        "title" => "The Cane",
        "venue" => "Back Theatre",
        "date"  => "2020-10-11 19:30",
    ],
    114801 => [
        "ID"    => "114801",
        "title" => "Madam Butterfly",
        "venue" => "Front Theatre",
        "date"  => "2020-10-12 19:30",
    ],
    105401 => [
        "ID"    => "105401",
        "title" => "Swan Lake",
        "venue" => "Front Theatre",
        "date"  => "2020-10-13 19:30",
    ],
];

Removing duplicates

In certain situations, we can use the fact that the index for an array has to be unique to our advantage. Imagine our original dataset contained duplicate entries. Indexing by ID would remove those duplicates for us. This may not be the true purpose of array_column, and so not to everyones taste, but it is shorter than.

$eventsByID = [];
foreach ($events as $event) {
    if (isset($event["ID"])) {
        $eventsByID[$event["ID"]] = $event;
    }
}

An array is always returned

A great thing about array_column is you will always get an array returned, this makes passing the result directly into another array based function somewhat safe.

$eventTitles = array_map("strtoupper", array_column($events, "title"));
// The result will be
[
    0 => "A MIDSUMMER NIGHT'S DREAM",
    1 => "THE CANE", 
    2 => "MADAM BUTTERFLY",
    3 => "SWAN LAKE"
]

Missing keys

If array_column encounters an array that does not contain the request index key, it fails silently. This is great for when we want to pluck data that may or might not be available.

$events = [
    [
        "ID"    => "101602",
        "title" => "A Midsummer Night's Dream",
    ],
    [
        "ID"    => "114601",
    ],
    [
        "ID"    => "114801",
    ],
    [
        "ID"    => "105401",
        "title" => "Swan Lake",
    ],
];

$eventTitles = array_column($events, "title");
// The result will be
[
    0 => "A Midsummer Night's Dream",
    1 => "Swan Lake",
]

Using objects

It is possible to use array_column with objects too, and it’s used in the exact same way.

$events = [
    (object) => 	[
        "ID"    => "101602",
        "title" => "A Midsummer Night's Dream",
        "venue" => "Top Theatre",
        "date"  => "2020-10-10 19:30",
    ],
    (object) => [
        "ID"    => "114601",
        "title" => "The Cane",
        "venue" => "Back Theatre",
        "date"  => "2020-10-11 19:30",
    ],
    ... // Events removed for brevity
];

$titles = array_column($events, "title")
// The result will be
[
    0 => "A Midsummer Night's Dream",
    1 => "The Cane", 
    2 => "Madam Butterfly",
    3 => "Swan Lake"
]

In summary

From now on, any time you have written a small foreach loop to extract data from a larger set, ask yourself can I use an array_column here for simplicity.

For more see the official PHP documentation for array_column.