SymfonyWorld Online 2022 Winter Edition

array_map

(PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8)

array_mapПрименяет callback-функцию ко всем элементам указанных массивов

Описание

array_map(?callable $callback, array $array, array ...$arrays): array

Функция array_map() возвращает массив (array), содержащий результаты применения callback-функции к соответствующему элементу arrayarrays, если указано больше массивов), используемого в качестве аргумента callback-функции. Количество параметров, передаваемых callback-функции, должно совпадать с количеством массивов, переданным функции array_map(). Лишние входные массивы игнорируются. Если предоставлено недостаточное количество аргументов, выбрасывается ArgumentCountError.

Список параметров

callback

callable, применяемая к каждому элементу в каждом массиве.

null может быть передан в качестве значения callback для выполнения zip операции с несколькими массивами. Если указан только array, array_map() вернёт входной массив.

array

Массив, к которому применяется callback-функция.

arrays

Дополнительные массивы для обработки callback-функцией.

Возвращаемые значения

Возвращает массив, содержащий результаты применения callback-функции к соответствующему элементу arrayarrays, если указано больше массивов), используемого в качестве аргумента для callback-функции.

Возвращённый массив сохранит ключи аргумента массива тогда и только тогда, когда будет передан ровно один массив. Если передано более одного массива, возвращённый массив будет иметь последовательные целочисленные ключи.

Список изменений

Версия Описание
8.0.0 Если параметр callback ожидает, что будет передано значение по ссылке, функция теперь выдаст ошибку уровня E_WARNING.

Примеры

Пример #1 Пример использования array_map()

<?php
function cube($n)
{
    return (
$n $n $n);
}

$a = [12345];
$b array_map('cube'$a);
print_r($b);
?>

В результате переменная $b будет содержать:

Array
(
    [0] => 1
    [1] => 8
    [2] => 27
    [3] => 64
    [4] => 125
)

Пример #2 Использование array_map() вместе с лямбда-функцией

<?php
$func 
= function(int $value): int {
    return 
$value 2;
};

print_r(array_map($funcrange(15)));

// Или с PHP 7.4.0:

print_r(array_map(fn($value): int => $value 2range(15)));

?>
Array
(
    [0] => 2
    [1] => 4
    [2] => 6
    [3] => 8
    [4] => 10
)

Пример #3 Пример использования array_map(): обработка нескольких массивов

<?php
function show_Spanish(int $nstring $m): string
{
    return 
"Число {$n} по-испански - {$m}";
}

function 
map_Spanish(int $nstring $m): array
{
    return [
$n => $m];
}

$a = [12345];
$b = ['uno''dos''tres''cuatro''cinco'];

$c array_map('show_Spanish'$a$b);
print_r($c);

$d array_map('map_Spanish'$a $b);
print_r($d);
?>

Результат выполнения данного примера:

// вывод $c
Array
(
    [0] => Число 1 по-испански - uno
    [1] => Число 2 по-испански - dos
    [2] => Число 3 по-испански - tres
    [3] => Число 4 по-испански - cuatro
    [4] => Число 5 по-испански - cinco
)

// вывод $d
Array
(
    [0] => Array
        (
            [1] => uno
        )

    [1] => Array
        (
            [2] => dos
        )

    [2] => Array
        (
            [3] => tres
        )

    [3] => Array
        (
            [4] => cuatro
        )

    [4] => Array
        (
            [5] => cinco
        )

)

Обычно при обработке двух или более массивов, они имеют одинаковую длину, так как callback-функция применяется параллельно к соответствующим элементам массивов. Если массивы имеют различную длину, более короткие из них дополняется элементами с пустыми значениями до длины самого длинного массива.

Интересным эффектом при использовании этой функции является создание массива массивов, что может быть достигнуто путём использования значения null в качестве имени callback-функции.

Пример #4 Выполнение zip операции с массивами

<?php
$a 
= [12345];
$b = ['one''two''three''four''five'];
$c = ['uno''dos''tres''cuatro''cinco'];

$d array_map(null$a$b$c);
print_r($d);
?>

Результат выполнения данного примера:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => one
            [2] => uno
        )

    [1] => Array
        (
            [0] => 2
            [1] => two
            [2] => dos
        )

    [2] => Array
        (
            [0] => 3
            [1] => three
            [2] => tres
        )

    [3] => Array
        (
            [0] => 4
            [1] => four
            [2] => cuatro
        )

    [4] => Array
        (
            [0] => 5
            [1] => five
            [2] => cinco
        )

)

Пример #5 null callback только с array

<?php
$array 
= [123];
var_dump(array_map(null$array));
?>

Результат выполнения данного примера:

array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  int(3)
}

Пример #6 Использование array_map() со строковыми ключами

<?php
$arr 
= ['stringkey' => 'value'];
function 
cb1($a) {
    return [
$a];
}
function 
cb2($a$b) {
    return [
$a$b];
}
var_dump(array_map('cb1'$arr));
var_dump(array_map('cb2'$arr$arr));
var_dump(array_map(null,  $arr));
var_dump(array_map(null$arr$arr));
?>

Результат выполнения данного примера:

array(1) {
  ["stringkey"]=>
  array(1) {
    [0]=>
    string(5) "value"
  }
}
array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(5) "value"
    [1]=>
    string(5) "value"
  }
}
array(1) {
  ["stringkey"]=>
  string(5) "value"
}
array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(5) "value"
    [1]=>
    string(5) "value"
  }
}

Пример #7 array_map() - ассоциативные массивы

Хотя array_map() напрямую не поддерживает использование ключа массива в качестве входных данных, это можно смоделировать с помощью array_keys().

<?php
$arr 
= [
    
'v1' => 'Первый выпуск',
    
'v2' => 'Второй выпуск',
    
'v3' => 'Третий выпуск',
];

// Примечание: До версии 7.4.0 вместо этого используйте более длинный синтаксис для анонимных функций.
$callback fn(string $kstring $v): string => "$k - это $v";

$result array_map($callbackarray_keys($arr), array_values($arr));

var_dump($result);
?>

Результат выполнения данного примера:

array(3) {
  [0]=>
  string(24) "v1 - это Первый выпуск"
  [1]=>
  string(25) "v2 - это Второй выпуск"
  [2]=>
  string(24) "v3 - это Третий выпуск"
}

Смотрите также

  • array_filter() - Фильтрует элементы массива с помощью callback-функции
  • array_reduce() - Итеративно уменьшает массив к единственному значению, используя callback-функцию
  • array_walk() - Применяет заданную пользователем функцию к каждому элементу массива

add a note

User Contributed Notes 8 notes

up
27
lukasz dot mordawski at gmail dot com
8 years ago
Let's assume we have following situation:

<?php
class MyFilterClass {
    public function
filter(array $arr) {
        return
array_map(function($value) {
            return
$this->privateFilterMethod($value);
        });
    }

    private function
privateFilterMethod($value) {
        if (
is_numeric($value)) $value++;
        else
$value .= '.';
    }
}
?>

This will work, because $this inside anonymous function (unlike for example javascript) is the instance of MyFilterClass inside which we called it.
I hope this would be useful for anyone.
up
19
elfe1021 at gmail dot com
8 years ago
Find an interesting thing that in array_map's callable function, late static binding does not work:
<?php
class A {
    public static function
foo($name) {
        return
'In A: '.$name;
    }

    public static function
test($names) {
        return
array_map(function($n) {return static::foo($n);}, $names);
    }
}

class
B extends A{
    public static function
foo($name) {
        return
'In B: '.$name;
    }
}

$result = B::test(['alice', 'bob']);
var_dump($result);
?>

the result is:
array (size=2)
  0 => string 'In A: alice' (length=11)
  1 => string 'In A: bob' (length=9)

if I change A::test to
<?php
   
public static function test($names) {
        return
array_map([get_called_class(), 'foo'], $names);
    }
?>

Then the result is as expected:
array (size=2)
  0 => string 'In B: alice' (length=11)
  1 => string 'In B: bob' (length=9)
up
18
Mahn
6 years ago
You may be looking for a method to extract values of a multidimensional array on a conditional basis (i.e. a mixture between array_map and array_filter) other than a for/foreach loop. If so, you can take advantage of the fact that 1) the callback method on array_map returns null if no explicit return value is specified (as with everything else) and 2) array_filter with no arguments removes falsy values.

So for example, provided you have:

<?php
$data
= [
    [
       
"name" => "John",
       
"smoker" => false
   
],
    [
       
"name" => "Mary",
       
"smoker" => true
   
],
    [
       
"name" => "Peter",
       
"smoker" => false
   
],
    [
       
"name" => "Tony",
       
"smoker" => true
   
]
];
?>

You can extract the names of all the non-smokers with the following one-liner:

<?php
$names
= array_filter(array_map(function($n) { if(!$n['smoker']) return $n['name']; }, $data));
?>

It's not necessarily better than a for/foreach loop, but the occasional one-liner for trivial tasks can help keep your code cleaner.
up
14
radist-hack at yandex dot ru
13 years ago
To transpose rectangular two-dimension array, use the following code:

array_unshift($array, null);
$array = call_user_func_array("array_map", $array);

If you need to rotate rectangular two-dimension array on 90 degree, add the following line before or after (depending on the rotation direction you need) the code above:
$array = array_reverse($array);

Here is example:

<?php
$a
= array(
  array(
1, 2, 3),
  array(
4, 5, 6));
array_unshift($a, null);
$a = call_user_func_array("array_map", $a);
print_r($a);
?>

Output:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 4
        )

    [1] => Array
        (
            [0] => 2
            [1] => 5
        )

    [2] => Array
        (
            [0] => 3
            [1] => 6
        )

)
up
7
stijnleenknegt at gmail dot com
13 years ago
If you want to pass an argument like ENT_QUOTES to htmlentities, you can do the follow.

<?php
$array
= array_map( 'htmlentities' , $array, array_fill(0 , count($array) , ENT_QUOTES) );
?>

The third argument creates an equal sized array of $array filled with the parameter you want to give with your callback function.
up
7
CertaiN
8 years ago
The most memory-efficient array_map_recursive().

<?php
function array_map_recursive(callable $func, array $arr) {
   
array_walk_recursive($arr, function(&$v) use ($func) {
       
$v = $func($v);
    });
    return
$arr;
}
?>
up
1
anonymous_user
6 months ago
/**
  * Function which recursively applies a callback to all values and also its
  * keys, and returns the resulting array copy with the updated keys and
  * values.
  * PHP's built-in function array_walk_recursive() only applies the passed
  * callback to the array values, not the keys, so this function simply applies
  * the callback to the keys too (hence the need of working with a copy,
  * as also updating the keys would lead to reference loss of the original
  * array). I needed something like this, hence my idea of sharing it here.
  *
  * @param    callable    $func     callback which takes one parameter (value
  *                                                   or key to be updated) and returns its
  *                                                   updated value
  *
  * @param    array          $arr      array of which keys and values shall be
  *                                                   get updated
  */

function array_map_recursive(
    callable $func,
    array $arr
) {

      // Initiate copied array which will hold all updated keys + values
      $result = [];

      // Iterate through the key-value pairs of the array
      foreach ( $arr as $key => $value ) {

        // Apply the callback to the key to create the updated key value
        $updated_key = $func( $key );

        // If the iterated value is not an array, that means we have reached the
        // deepest array level for the iterated key, so in that case, assign
        // the updated value to the updated key value in the final output array
        if ( ! is_array( $value ) ) {

          $result[$updated_key] = $func( $value );

        } else {

          // If the iterated value is an array, call the function recursively,
          // By taking the currently iterated value as the $arr argument
          $result[$updated_key] = array_map_recursive(
            $func,
            $arr[$key]
          );

        }

      } // end of iteration through k-v pairs

      // And at the very end, return the generated result set
      return $result;

    } // end of array_map_recursive() function definition
up
-1
Walf
3 months ago
A general solution for the problem of wanting to know the keys in the callback, and/or retain the key association in the returned array:

<?php

/**
* Like array_map() but callback also gets passed the current key as the
* first argument like so:
* function($key, $val, ...$vals) { ... }
* ...and returned array always maintains key association, even if multiple
* array arguments are passed.
*/

function array_map_assoc(callable $callback, array $array, array ...$arrays) {
   
$keys = array_keys($array);
   
array_unshift($arrays, $keys, $array);
    return
array_combine($keys, array_map($callback, ...$arrays));
}

?>

Because it uses array_map() directly, it behaves the same way in regard to ignoring the keys of subsequent array arguments. It also has the same variadic signature.
To Top