Tuesday 14 August 2018

PHP Array Iteration Functions

On this page we demonstrate and describe how to use the PHP iteration functions: array_walkarray_map, and array_filter. We start with array_walk. Another page covers control structures and language constructs used to traverse arrays.

array_walk

The array_walk function applies a callback function you specify to every element of the array passed to it. Each element's value and key are passed to the callback function in turn. The following basic example demonstrates by using echo to display each key and value:
$pets = ['Morie', 'Miki', 'Halo', 'lab' => 'Winnie'];
// arguments: array, callback function, additional data (optional)
array_walk( $pets, function($val, $key) { echo "$key => $val \n"; } );
/* output (page source view)
0 => Morie 
1 => Miki 
2 => Halo 
lab => Winnie 
*/
By default, the array_walk function does not modify the array passed to it. However, the value can be passed by reference to change the values in the array, as we demonstrate here:
$ar = [1, 2, 3, 4];
// use & (reference sign) to change values in array
array_walk( $ar, function(&$val) { $val *= 2; } );
print_r($ar);
/* Array
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
) */
Although both the key and value are passed by array_walk to the callback function, we only use the value in the example above. You can supply additional data as the third argument to array_walk and pass it as the third argument to the callback function, as shown here:
$ar = [1, 2, 3, 4];
// pass 3 as 3rd argument
array_walk( $ar, function(&$val, $key, $num) { $val *= $num; }, 3 );
print_r($ar);
/* Array
(
    [0] => 3
    [1] => 6
    [2] => 9
    [3] => 12
) */
The array_walk function returns true or false depending on the success or failure of its invocation.

array_map

Pass a callback function and an array to array_map and it returns a new array based on the return value of the callback for each iteration as the values of the original array are passed to it in turn. A simple example demonstrates:
$ar = [1, 2, 3, 4];
// arguments: callback function, array
$ar2 = array_map( function($v) { return $v*2; }, $ar );
print_r($ar2);
/* Array
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
) */
The example above uses a custom user-supplied function. You can also use a built-in PHP function, as the next example demonstrates:
$ar = [ 'jan' => 'january', 'feb' => 'february', 
        'mar' => 'march', 'apr' => 'april' ];
$ar2 = array_map('ucfirst', $ar);
print_r($ar2);
/* Array
(
    [jan] => January
    [feb] => February
    [mar] => March
    [apr] => April
) */
Notice that array returned by array_map retains the string keys of the original array in the example above.
You can add additional arrays as arguments to array_map. The number of arguments passed to the callback function should equal the number of arrays passed to array_map. Even though the array_map function does not pass the array elements' keys to the callback function, we can use the array_keys function to pass the array containing the keys as a separate argument.
$ar = [ 'jan' => 'january', 'feb' => 'february', 
        'mar' => 'march', 'apr' => 'april' ];

// example callback function for array_map
function monthInfo($a, $b) {
    return ucfirst($a) . ' is the abbreviation for ' . ucfirst($b);
}

$ar3 = array_map('monthInfo', array_keys($ar), $ar);
print_r($ar3);
/* Array
(
    [0] => Jan is the abbreviation for January
    [1] => Feb is the abbreviation for February
    [2] => Mar is the abbreviation for March
    [3] => Apr is the abbreviation for April
) */
If you pass null as the callback argument along with two or more arrays, the array_mapfunction will return an array of arrays, with each sub-array consisting of the corresponding elements in each array passed:
$ar = [ 'jan' => 'january', 'feb' => 'february', 
        'mar' => 'march', 'apr' => 'april' ];

// pass null as callback
$ar4 = array_map(null, array_keys($ar), $ar);
print_r($ar4);
/* Array
(
    [0] => Array
        (
            [0] => jan
            [1] => january
        )

    [1] => Array
        (
            [0] => feb
            [1] => february
        )

    [2] => Array
        (
            [0] => mar
            [1] => march
        )

    [3] => Array
        (
            [0] => apr
            [1] => april
        )

) */
You can use a custom callback function for more control over the resulting array of arrays, as the following demonstrates:
$ar = [ 'jan' => 'january', 'feb' => 'february', 
        'mar' => 'march', 'apr' => 'april' ];

$ar5 = array_map( function ($a, $b) { 
        return [ ucfirst($a), ucfirst($b) ]; 
    }, array_keys($ar), $ar);

print_r($ar5);
/* Array
(
    [0] => Array
        (
            [0] => Jan
            [1] => January
        )

    [1] => Array
        (
            [0] => Feb
            [1] => February
        )

    [2] => Array
        (
            [0] => Mar
            [1] => March
        )

    [3] => Array
        (
            [0] => Apr
            [1] => April
        )

) */
The number of elements in each array passed to array_map should be equal. If they don't match, empty array elements will be passed in their place as the corresponding values from each array are passed to the callback function.

array_filter

The array_filter function creates a new array by using a callback function to screen elements of the array passed to it. The following example demonstrates by selecting only the integer values from the original array:
$ar = [1, 'two', 'three', 4, 5, 'six'];
// arguments: array, callback function
$ar2 = array_filter( $ar, function($v) { return is_int($v); } );
print_r($ar2);
/* Array
(
    [0] => 1
    [3] => 4
    [4] => 5
) */
The callback function inspects each value of the passed array in turn and returns true to include that value in the resulting array. Notice that the array returned by the array_filterfunction retains the keys of the function passed to it.
A flag, ARRAY_FILTER_USE_KEY or ARRAY_FILTER_USE_BOTH, can be passed as the third argument to array_filter to use the key, or both value and key in the callback function:
$ar = [1, 'two' => 2, 'three', 4 => 'four', 5];

$ar2 = array_filter( $ar, function($v, $k) { 
        if ( is_int($v) && is_int($k) ) {
            return true;
        } 
    }, ARRAY_FILTER_USE_BOTH );
print_r($ar2);
/* Array
(
    [0] => 1
    [5] => 5
) */
If no callback argument is passed to the array_filter function, array values that convert to false will be excluded from the returned array. For example:
$ar = [0, 1, true, false, [], null, 'Yo'];

$ar2 = array_filter($ar);
var_dump($ar2)
/* array(3) {
  [1]=>
  int(1)
  [2]=>
  bool(true)
  [6]=>
  string(2) "Yo"
} */

0 comments:

Post a Comment