Filtering Arrays in PHP

Few PHP developers know how to manipulate arrays using PHP's built-in functionality. Here are three powerful applications of this function set and why you should use them in your code.

I discovered yesterday how few developers use array filtering in PHP. Sure, they know how to filter arrays, but like most sane people avoid any function within PHP that starts with [cci]array_[/cci]

After all, PHP’s array handling is flat out insane.

As a result, most developers will use [cci]for[/cci] loops to manually iterate over arrays. It works, but consumes several lines of code and generally looks ugly.

There are a handful of functions built into PHP that can be lifesavers when building a project.

Mapping Arrays

The most widely recognized PHP array method is [cci]array_map()[/cci]. With this method, you can “map” an arbitrary function to every element in an array.

Let’s say, for example, an API or database lookup gives you an array of numbers but for some reason all of these numbers are stored as strings. It would be far better if we could apply, say WordPress’ [cci]absint()[/cci] function to each item before using it elsewhere in our code.

// Get an array of strings from a data source
$our_array = get_some_data_from_somewhere();

// Turn those strings into integers
$our_array = array_map( 'absint', $our_array );

Filtering Arrays

Sometimes, an array contains a lot more data than we actually need to use. Perhaps its a collection of all WordPress posts and we want to specifically exclude certain posts that have been printed elsewhere on the page.[ref]In some cases, you might just run a second query. With a [cci]post__not_in[/cci] parameter, but then you’re running two queries. The second version is also not cachable.[/ref]

Luckily, the [cci]array_filter()[/cci] method allows us to iterate through our array and determine whether or not individual elements should remain in the collection:

// Get an array of strings from a data source
$our_array = get_some_data_from_somewhere();

// We want to exclude posts from the following array
$exclude = array( 15, 27, 123 );

// Now do the filter, using a closure
$filtered = array_filter( $our_array, function( $item ) use ( $exclude ) {
if ( in_array( $item->ID, $exclude ) ) {
return false;
}

return true;
} );

When the closure returns true, the current item will remain in the array. When it returns false, the item is skipped. You could just filter the array back to itself – storing the result of [cci]array_filter()[/cci] in a second variable allows us to be nondestructive in our operation (if we need the original array again for any reason).

Reducing Arrays

My personal favorite, though, is [cci]array_reduce()[/cci]. Like [cci]array_filter()[/cci] above, it can be used to filter an array down to a specific subset. Since it builds up an internal array (the reduce function applies iteratively to the carrying array), you can also manipulate the keys of the array at the same time.

For example, let’s say you’re working again with an array of posts in WordPress. You want to strip out 2 posts that have already been used on the page. At the same time, you want to convert your numerically-indexed array to an associative array keyed by post IDs.

// Get an array of strings from a data source
$our_array = get_some_data_from_somewhere();

// We want to exclude posts from the following array
$exclude = array( 15, 27, 123 );

// Now reduce the array, using a closure
$reduced = array_reduce( $our_array, function( $carry, $item ) use ( $exclude ) {
if ( ! in_array( $item->ID, $exclude ) ) {
$carry[ $post->ID ] = $item;
}

return $carry;
} );

You’re effectively using [cci]array_reduce()[/cci] to filter the array, but killing two birds with one stone by rekeying the array at the same time.

What other PHP array functions do you use?