• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • array_map()

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

    为数组的每个元素应用回调函数

    说明

    array_map(callable$callback,array $array1[,array $...]): array

    array_map():返回数组,是为$array1每个元素应用$callback函数之后的数组。$callback函数形参的数量和传给array_map()数组数量,两者必须一样。

    参数

    $callback

    回调函数,应用到每个数组里的每个元素。

    $array1

    数组,遍历运行$callback函数。

    数组列表,每个都遍历运行$callback函数。

    返回值

    返回数组,包含$callback函数处理之后$array1的所有元素。

    范例

    Example #1array_map()例子

    <?php
    function cube($n)
    {
        return($n * $n * $n);
    }
    $a = array(1, 2, 3, 4, 5);
    $b = array_map("cube", $a);
    print_r($b);
    ?>
    

    这使得$b成为:

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

    Example #2array_map()使用匿名函数(PHP 5.3.0 起)

    <?php
    $func = function($value) {
        return $value * 2;
    };
    print_r(array_map($func, range(1, 5)));
    ?>
    
    Array
    (
        [0] => 2
        [1] => 4
        [2] => 6
        [3] => 8
        [4] => 10
    )
    

    Example #3array_map():使用更多的数组

    <?php
    function show_Spanish($n, $m)
    {
        return("The number $n is called $m in Spanish");
    }
    function map_Spanish($n, $m)
    {
        return(array($n => $m));
    }
    $a = array(1, 2, 3, 4, 5);
    $b = array("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);
    ?>
    

    以上例程会输出:

    // printout of $c
    Array
    (
        [0] => The number 1 is called uno in Spanish
        [1] => The number 2 is called dos in Spanish
        [2] => The number 3 is called tres in Spanish
        [3] => The number 4 is called cuatro in Spanish
        [4] => The number 5 is called cinco in Spanish
    )
    // printout of $d
    Array
    (
        [0] => Array
            (
                [1] => uno
            )
        [1] => Array
            (
                [2] => dos
            )
        [2] => Array
            (
                [3] => tres
            )
        [3] => Array
            (
                [4] => cuatro
            )
        [4] => Array
            (
                [5] => cinco
            )
    )
    

    传入两个及以上的数组时,它们元素数量将会相同。因为回调函数会并行地处理相互对应的元素。如果几个数组的元素数量不一致:空元素会扩展短那个数组,直到长度和最长的数组一样。

    此函数有个有趣的用法:传入NULL作为回调函数的名称,将创建多维数组(一个数组,内部包含数组。)

    多维数组:创建数组,内部包含数组

    <?php
    $a = array(1, 2, 3, 4, 5);
    $b = array("one", "two", "three", "four", "five");
    $c = array("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
            )
    )
    

    如果仅传入一个数组,键(key)会保留;传入多个数组,键(key)是整型数字的序列。

    Example #5array_map()键(key)是 string

    <?php
    $arr = array("stringkey" => "value");
    function cb1($a) {
        return array ($a);
    }
    function cb2($a, $b) {
        return array ($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"
      }
    }
    

    参见

    • array_filter() 用回调函数过滤数组中的单元
    • array_reduce() 用回调函数迭代地将数组简化为单一的值
    • array_walk() 使用用户自定义函数对数组中的每个元素做回调处理
    • callback类型的信息
    I was miffed that array_map didn't have a way to pass values *and* keys to the callback, but then I realized I could do this:
    function callback($k, $v) { ... }
    array_map( "callback", array_keys($array), $array);
    If you need to call a static method from array_map, this will NOT work:
    <?PHP
    array_map('myclass::myMethod' , $value);
    ?>
    Instead, you need to do this:
    <?PHP
    array_map( array('myclass','myMethod') , $value);
    ?>
    It is helpful to remember that this will work with any PHP function which expects a callback argument.
    PHP 5.3 enables us to use inline anonymous functions with array_map, cleaning up the syntax slightly.
    <?php
    $data = array(
        array('id' => 1, 'name' => 'Bob', 'position' => 'Clerk'),
        array('id' => 2, 'name' => 'Alan', 'position' => 'Manager'),
        array('id' => 3, 'name' => 'James', 'position' => 'Director')
    );
    $names = array_map(
        function($person) { return $person['name']; },
        $data
    );
    print_r($names);
    ?>
    This was possible (although not recommended) in prior versions of PHP 5, via create_function().
    <?php
    $names = array_map(
        create_function('$person', 'return $person["name"];'),
        $data
    );
    ?>
    You're less likely to catch errors in the latter version because the code is passed as string arguments.
    These are alternatives to using a foreach:
    <?php
    $names = array();
    foreach ($data as $row) {
        $names[] = $row['name'];
    }
    ?>
    
    You can use array_map with PHP native functions as well as user functions. This is very handy if you need to sanitize arrays. 
    <?php
    $integers = array_map ('intval', $integers);
    $safeStrings = array_map ('mysql_real_escape_string', $unsafeStrings);
    ?>
    
    This function behaves exactly like array_map but additionally does not reject non-array arguments. Instead, it transforms them with the array_fill function to a constant valued array of required length according to the other array arguments (if any) and executes the original array_map function.
    <?php
    function array_map2() {
      $args = func_get_args();
      $callback = array_shift($args);
      
      $args = array_map(
          create_function('$a,$max','return is_array($a)? $a: array_fill(0,$max,$a);'),
          $args,array_fill(0,count($args),array_reduce($args,
          create_function('$v,$w','return max($v,is_array($w)? count($w): 1);'))));
      array_unshift($args,$callback);
      
      return call_user_func_array("array_map",$args);
    }
    ?>
    Example:
    <?php
    $get = "first=value1&second=value2&third=value3";
    print_r(array_map2("explode","=",explode("&",$get)));
    ?>
    would print out: 
    <?php
    Array
    (
      [0] => Array
        (
          [0] => first
          [1] => value1
        )
      [1] => Array
        (
          [0] => second
          [1] => value2
        )
      [2] => Array
        (
          [0] => third
          [1] => value3
        )
    )
    ?>
    /pmf
    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
        )
    )
    Simplest array_map_recursive() implemention.
    <?php
    function array_map_recursive(callable $func, array $array) {
      return filter_var($array, \FILTER_CALLBACK, ['options' => $func]);
    }
    ?>
    
    If you are using Namespaces, the array_map callback expects the Fully Qualified NameSpace to be used.
    For example, this won't work:
    <?php
    namespace Test;
    function mapping_function($var) {
      ...
    }
    array_map('mapping_function', $array); //won't find 'mapping_function' here.
    ?>
    This, however, will work:
    <?php
    namespace Test;
    function mapping_function($var) {
      ...
    }
    array_map('Test\mapping_function', $array); //using FQNS.
    ?>
    
    Note that the $arr argument has to be an array, not just a Traversable/Iterator.
    For instance this won't work:
    <?php
    $documents = $mongo->db->collection->find();
    // $documents is Traversable by foreach
    $ids = array_map(function($document) {
     return $document['_id'];
    }, $objects);
    // $ids will now be NULL, because $documents wasn't an Array
    ?>
    A solution is to first use iterator_to_array():
    <?php
    $ids = array_map(function($document) {
     return $document['_id'];
    }, iterator_to_array($objects));
    // $ids will now be an array of ['_id']s
    ?>
    But this is not very efficient: two cycles instead of one. Another solution is to use foreach: one cycle and a lot of freedom (and in the same scope).
    Hope I'm not late to the party, here's my function to apply array_map to the *keys* of an array.
    Extra array arguments will be used for the callback function's parameters just like with array_map, with the difference that a string is also allowed: it will just be used to create an array of appropriate length with as each value that string. Arrays are left alone (and will be padded with nulls by array_map as needed).
    <?php
    //_________________________________________________
    // array_map_keys($callback, $array, [$args, ..]) /
    function array_map_keys($callback, $array /* [, $args ..] */) {
     $args = func_get_args();
     if (! is_callable($callback)) trigger_error("first argument (callback) is not a valid function", E_USER_ERROR);
     if (! is_array($array)) trigger_error("second argument must be an array", E_USER_ERROR);
     $args[1] = array_keys($array);
     // If any additional arguments are not arrays, assume that value is wanted for every $array item.
     // array_map() will pad shorter arrays with Null values
     for ($i=2; $i < count($args); $i++) { 
      if (! is_array($args[$i])) {
       $args[$i] = array_fill(0, count($array), $args[$i]);
      }
     }
     return array_combine(call_user_func_array('array_map', $args), $array);
    }
    // Some examples:
    $arr = array('foo'=>123, 'bar'=>456);
    // simply uppercase keys:
    var_dump(array_map_keys('strtoupper', $arr));
    // or..
    var_dump(array_map_keys(function($input) {return strtoupper($input);}, $arr));
    // >> array(2) { ["FOO"]=>int(123) , ["BAR"]=> int(456) }
    // Add a prefix 'myvar_':
    var_dump(array_map_keys(function($input, $prefix) {return $prefix.$input;}, $arr, 'myvar_'));
    // >> array(2) { ["myvar_foo"]=>int(123) , ["myvar_bar"]=>int(456) }
    // Apart from the (static string) prefix, we also number them:
    $arr = array('foo'=>123, 'bar'=>456, 'bazz'=>789, 'yadda'=>'0AB');
    var_dump(array_map_keys(function($input, $middle, $number) {return $number.':'.$middle.$input;}, $arr, 'myvar_', range(1, count($arr))));
    // >> array(4) { ["1:myvar_foo"]=>int(123) , ["2:myvar_bar"]=>int(456) , ["3:myvar_bazz"]=>int(789) , ["4:myvar_yadda"]=>string(3) "0AB" }
    ?>
    
    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.
    Here is how to perform an operation on some of the elements of an array:
    <?php
    $an_array = array(
      'item1' => 0,
      'item2' => 0,
      'item3' => 0,
      'item4' => 0,
      'item5' => 0,
    );
    $items_to_modify = array('item1', "item3");
     array_map(function ($value) use (&$an_array ) {
       $an_array [$value] = (boolean)$an_array [$value];  //example operation:
     }, $items_to_modify);
    ?>
    This will take the original array and perform an action only on items specified on the second array items. Use of & symbol in the use statement makes the array_map access the variable as a reference in an outer scope.
    This makes code easily extendable.
    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.
    array_map() can be applied to assoc arrays without affecting the keys
    You can easily remove all HTML tags from $_GET or $_POST variables using something like this:
    <?php
    $_POST = array_map('strip_tags', $_POST);
    $_GET = array_map('strip_tags', $_GET);
    ?>
    This is useful when you don't want to parse HTML.
    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)
    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.
    The following function does exaclty the same thing of array_map. However, maintains the same index of the input arrays
    <?php
      function array_map_keys($param1,$param2,$param3=NULL)
      {
        $res = array();
        if ($param3 !== NULL)
        {
          foreach(array(2,3) as $p_name)
          {
            if (!is_array(${'param'.$p_name}))
            {
              trigger_error(__FUNCTION__.'(): Argument #'.$p_name.' should be an array',E_USER_WARNING);
              return;
            }
          }
          foreach($param2 as $key => $val)
          {
            $res[$key] = call_user_func($param1,$param2[$key],$param3[$key]);
          }
        }
        else
        {
          if (!is_array($param2))
          {
            trigger_error(__FUNCTION__.'(): Argument #2 should be an array',E_USER_WARNING);
            return;
          }
          foreach($param2 as $key => $val)
          {
            $res[$key] = call_user_func($param1,$param2[$key]);
          }
        }
        return $res;
      }
    ?>
    For instance:
    <?php
      $arr1 = array(
        '3' => 'a',
        '4' => 'b',
        '5' => 'c'
        );
      $arr2 = array(
        '3' => 'd',
        '4' => 'e',
        '5' => 'f'
        );
      $arr3 = array_map_keys(create_function('$a,$b','return $a.$b;'),$arr1,$arr2);
      print_r($arr3);
    ?>
    The result will be:
    Array
    (
      [3] => ad
      [4] => be
      [5] => cf
    )
    Array
    (
      [result] => Array
        (
          [0] => Array
            (
              [child] => Array
                (
                  [5629378c2bad8cac1900002a] => Array
                    (
                      [_id] => MongoId Object
                        (
                          [$id] => 5629378c2bad8cac19000029
                        )
                      [name] => Category 1
                      [hasChild] => 0
                    )
                  [562937c02bad8ca41900002a] => Array
                    (
                      [_id] => MongoId Object
                        (
                          [$id] => 562937c02bad8ca419000029
                        )
                      [name] => Category 1
                      [hasChild] => 0
                    )
                  [562937dd2bad8c9c1900002b] => Array
                    (
                      [_id] => MongoId Object
                        (
                          [$id] => 562937dd2bad8c9c1900002a
                        )
                      [name] => Category 1
                      [hasChild] => 0
                    )
                )
            )
        )
      [ok] => 1
    )
    Trim above code neatly using
    print_r(array_map(null, $result['result'][0]['child']));
    Array
    (
      [5629378c2bad8cac1900002a] => Array
        (
          [_id] => MongoId Object
            (
              [$id] => 5629378c2bad8cac19000029
            )
          [name] => Category 1
          [hasChild] => 0
        )
      [562937c02bad8ca41900002a] => Array
        (
          [_id] => MongoId Object
            (
              [$id] => 562937c02bad8ca419000029
            )
          [name] => Category 1
          [hasChild] => 0
        )
      [562937dd2bad8c9c1900002b] => Array
        (
          [_id] => MongoId Object
            (
              [$id] => 562937dd2bad8c9c1900002a
            )
          [name] => Category 1
          [hasChild] => 0
        )
    )
    Here is an example for php 5.4 and greater, using a closure:
    <?php
    $myList = [1,2,3,4];
    $mappedList = array_map(function($value){
      return $value * 2;
    }, $myList);
    var_dump($mappedList);
    array(4) {
     [0]=>int(2)
     [1]=>int(4)
     [2]=>int(6)
     [3]=>int(8)
    }
    ?>
    This is useful when you don't want/need to define a function just so it can be used with the map function.
    In case of you need to recursively bypass a function over the itens of an array, you can use it
    <?php
      function array_map_recursive($callback, $array) {
        foreach ($array as $key => $value) {
          if (is_array($array[$key])) {
            $array[$key] = array_map_recursive($callback, $array[$key]);
          }
          else {
            $array[$key] = call_user_func($callback, $array[$key]);
          }
        }
        return $array;
      }
    ?>
    -----------------------------------------------------------------------
    <?php
      $strings = array(
        'The',
        array(
          'quick',
          'fox',
          array(
            'brown',
            'jumps',
            array(
              'over',
              array(
                'the',
                array(
                  'lazy',
                  array(
                    'dog'
                  )
                )
              )
            )
          )
        )
      );
      print_r($strings);
      $hashedString = array_map_recursive('md5', $strings);
      print_r($hashedString);
    ?>
    ------------------------------------------------------------------------
    Testing it, you'll obtain
    <?php
    /* Original array */
    array (
     0 => 'The',
     1 =>
     array (
      0 => 'quick',
      1 => 'fox',
      2 =>
      array (
       0 => 'brown',
       1 => 'jumps',
       2 =>
       array (
        0 => 'over',
        1 =>
        array (
         0 => 'the',
         1 =>
         array (
          0 => 'lazy',
          1 =>
          array (
           0 => 'dog',
          ),
         ),
        ),
       ),
      ),
     ),
    );
    /* Recursived array */
    array (
     0 => 'a4704fd35f0308287f2937ba3eccf5fe',
     1 =>
     array (
      0 => '1df3746a4728276afdc24f828186f73a',
      1 => '2b95d1f09b8b66c5c43622a4d9ec9a04',
      2 =>
      array (
       0 => '6ff47afa5dc7daa42cc705a03fca8a9b',
       1 => '55947829059f255e4ba2f536a2ae99fe',
       2 =>
       array (
        0 => '3b759a9ca80234563d87672350659b2b',
        1 =>
        array (
         0 => '8fc42c6ddf9966db3b09e84365034357',
         1 =>
         array (
          0 => '0ffe34b4e04c2b282c5a388b1ad8aa7a',
          1 =>
          array (
           0 => '06d80eb0c50b49a509b49f2424e8c805',
          ),
         ),
        ),
       ),
      ),
     ),
    );
    ?>
    Hope it helps you.
    Cheers.
    I realize this function is easy enough to make, but this is a faster version (twice the speed) of [a function] which I find incredibly useful.
    <?php
    function array_pluck($key, $input) {
      if (is_array($key) || !is_array($input)) return array();
      $array = array();
      foreach($input as $v) {
        if(array_key_exists($key, $v)) $array[]=$v[$key];
      }
      return $array;
    }
    ?>
    Usage: 
    <?php $ids = array_pluck('id', $users); ?>
    
    Adding method support to function by Andref (multidimensionalArrayMap).
    function array_map_r( $func, $arr )
    {
      $newArr = array();
      
      foreach( $arr as $key => $value )
      {
        $newArr[ $key ] = ( is_array( $value ) ? array_map_r( $func, $value ) : ( is_array($func) ? call_user_func_array($func, $value) : $func( $value ) ) );
      }
        
      return $newArr;
    }
    array_map_r('function', array());
    or
    array_map_r(array('class', 'method'), array());
    Another way to array_map htmlentities with a specific quote style is to create a function that does it and map that function
    <?php
    function map_entities( $str ) {
      return htmlentities( $str, ENT_QUOTES );
    }
    $good_array = array_map ( 'map_entities', $bad_array );
    ?>
    
    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;
    }
    ?>
    
    Why not an array of callbacks?
    <?php
    function array_maps($callbacks, $array) {
      if (!$callbacks) { return $array; }
      
      if (!is_array($callbacks) && is_string($callbacks) && function_exists($callbacks)) {
        return array_map($callbacks, $array);
      }
      foreach($callbacks as $callback) {
        if (function_exists($callback)) {
        $array = array_map($callback, $array);
        }
      }
      return $array;
    }
    ?>
    
    Why not use 
    mb_convert_case($str, MB_CASE_TITLE, "UTF-8");
    Works for me! :)
    this function is really nice for recursion in php!!!
    example in a class:
    <?php
    class test{
      //private $container = array();
      
      final public function add($key, $value){
         /* recursion */
         if(is_array($value)){
            array_map(array($this, __FUNCTION__), array_keys($value), array_values($value));
         }
         /* procedural */
         else{
           echo $key.' => '.$value.'<br/>'.PHP_EOL;
           // do stuff...
           // if(!isset($this->container[$key])){ 
           //    $this->container[$key] = $value;
           // }
           //else{ // trigger_error() xor throw new Exception?
           //     echo 'allready exists!<br/>'.PHP_EOL;
           //}
         }
      }
    }
    //
    $array = array (
                    'one'  => 'value1',
                    'two'  => 'value2',
                    'three' => 'value3'
                  );
    $t = new test;
    $t->add($array);
    ?>
    you could easiely do this without a class too offcourse!
    used in php 5.2.5
    An alternative for recursive mapping;
    <?php
    function array_map_recursive($fn, $arr) {
      $rarr = array();
      foreach ($arr as $k => $v) {
        $rarr[$k] = is_array($v)
          ? array_map_recursive($fn, $v)
          : $fn($v); // or call_user_func($fn, $v)
      }
      return $rarr;
    }
    function sqr($x) {
      return "$x ^ 2 = ". ($x * $x);
    }
    $a = array(1, 2, 3, array(4, array(5)));
    $b = array_map_recursive("sqr", $a);
    print_r($b);
    ?>
    Array
    (
      [0] => 1 ^ 2 = 1
      [1] => 2 ^ 2 = 4
      [2] => 3 ^ 2 = 9
      [3] => Array
        (
          [0] => 4 ^ 2 = 16
          [1] => Array
            (
              [0] => 5 ^ 2 = 25
            )
        )
    )
    A note when doing something allong the lines of:
    <?php
    class foo {
     var $var;
     function bar() {
       array_map(array($this, "baz"), array(1,2,3));
     }
     function baz($arg) {
      $this->var = $this->var + $arg;
     }
    }
    ?>
    This will *not* work as expected. You need to pass $this by reference as with:
    array_map(array(&$this, "baz"), array(1,2,3));
    or you'll be making a copy of the object each time, changing a value, then throwing the result away.
    Short-hands to "array_map", fill parameter arrays:
    <?php
    /**
     * Applies the callback to the values of the given list. Mix `array_map()` and `iterator_apply()`.
     * 
     * @param callable $callback Callback function to run for each value in list.
     * @param array $parameters Callback parameters, contain the keys "values" and "keys"(optional, auto fill).
     * @return array
     */
    function arr_map(?callable $callback, array $parameters): array
    {
      if (empty($parameters['values'])) {
        throw new \InvalidArgumentException('Parameters must contain the key "values"');
      }
      if (! \is_iterable($parameters['values'])) {
        throw new \InvalidArgumentException('Parameter "values" must be iterable');
      }
      if (\is_object($parameters['values'])) {
        $parameters['values'] = \iterator_to_array($parameters['values']);
      }
      $keys = \array_keys($parameters['values']);
      \array_walk(
        $parameters,
        function (&$value, $key) use ($keys) {
          if ($key == 'keys') {
            $value = $keys;
          } elseif ($key != 'values') {
            $value = \array_fill_keys($keys, $value);
          }
        }
      );
      return \array_map($callback, ...\array_values($parameters));
    }
    ?>
    Usage, add prefix to values:
    <?php
    $array = range('a', 'z');
    $result = arr_map('sprintf', ['prefix_%s', 'value' => $array]));
    $iterator = new ArrayIterator($array);
    $result2 = arr_map('sprintf', ['prefix_%s', 'values' => $iterator]);
    ?>
    
    Simple obvious thing to keep in mind:
    the number of arrays passed as arguments to an array_map() function should correspond to the number of parameters defined in the callback otherwise,say if you write a function with n parameters and supply m arrays to the array_map such that m>n,array_map() ignores params at n+1 onwards. but no error or notice is issued. Of course supplying fewer arguments than declared in the function declaration throws an 
    ArgumentCountError
    please notice if a class not found, you may pass the class name with namespace
    <?php
    namespace Demo
    class A{
     public static method hi(){}
    }
    ?>
    you should call like this
    <?php
     array_map('Demo\A::hi', [])
    ?>
    
    At the current time there is no way in php to map both keys and values, but the impementation is pretty simple:
    <?php 
    // array_map() that works with both keys and values
    function array_map_keys(array $a1, \Closure $f_k_mapper = null, \Closure $f_v_mapper = null): array {
      $f_k_mapper = $f_k_mapper ?? function ($s) {return $s;};
      $f_v_mapper = $f_v_mapper ?? function ($s) {return $s;};
      $a2 = [];
      foreach ($a1 as $k1 => $v) {
        $a2[$f_k_mapper($k1)] = $f_v_mapper($v);
      }
      return $a2;
    }
    ?>
    
    The words "is an immutable implementation" are missing...
    Essentially the collection you send in can be sent to the same var you operate after map has completed, thus explicitly overwriting, but importantly the input array is not modified, so the method is (as it should be) immutable. This means if you send in `$array1` and assign result to `$array2`, you'll still have `$array1` as it was prior to the map function call.
    This is entirely separate from foreach modification semantics where mostly I've seen a mix of immutable (assigning to a new object) and mutable (using key and array to update in-place `$arrayinput[$key] = doSomethingWith($value)`.
    This is not a comment on the internal workings but has been tested on 5.4, 5.6, 7.0 and 7.1
    If you're looking for a way to get a specific set of key values (ala "pluck") you can just use array_column([['id' => 1]], 'id').
    If you need to map both the keys AND the values of an array (be it associative or not) you can use a function like this:
    <?php
    function array_map_assoc($callback, $arr) {
      $remapped = array();
      foreach($arr as $k => $v)
       $remapped += $callback($k, $v);
      return $remapped;
    }
    ?>
    For example:
    <?php
    $arr = array(
      'cat' => 'tom',
      'mouse' => 'jerry'
    );
    $newArr = array_map_assoc(function($k, $v) {
      return array(
       'another_' . $k => $v . '\'s clone'
      );
    }, $arr);
    print_r($newArr);
    ?>
    The example above will output:
    <?php
    Array
    (
      [another_cat] => tom's clone
      [another_mouse] => jerry's clone
    )
    ?>
    You can even use it with non associative arrays, for example to shift the indexes while changing the values:
    <?php
    $arr = array(
      0 => 'tom',
      1 => 'jerry'
    );
    $newArr = array_map_assoc(function($k, $v) {
      return array(
       ($k + 10) => $v . '\'s clone'
      );
    }, $arr);
    print_r($newArr);
    Array
    (
      [10] => tom's clone
      [11] => jerry's clone
    )
    ?>
    
    PHP 5.5.14
    <?php
    $columns = range(1, 100000);
    $time = microtime(true);
    /*
    0.067003011703491 sec
    24903680 byte
     */
    array_map(function ($value) {
      return 'p.' . $value;
    }, $columns);
    /*
    0.042001962661743 sec
    19398656 byte
     */
    foreach ($columns as $key => $column) {
      $columns[$key] = 'p.' . $column;
    }
    /*
    0.05500316619873 sec
    10747904 byte
     */
    array_walk($columns, function (&$value, $key) {
      $value = 'p.' . $value;
    });
    /*
    0.0260009765625 sec
    10747904 byte
     */
    foreach ($columns as &$column) {
      $column = 'p.' . $column;
    }
    echo microtime(true) - $time . "\n" . memory_get_peak_usage(true) . "\n";
    A function to map an array working also with its key.
    <?php
      function array_mapk($callback, $array) {
        $newArray = array();
        foreach ($array as $k => $v) {
          $newArray[$k] = call_user_func($callback, $k, $v);
        }
        return $newArray;
      }
    ?>
    Usage:
    <?php
      $dados = array();
      $dados['cep'] = "32340-070";
      $dados['initial'] = 100;
      $dados['final'] = 300;
      $dados['processed'] = 1;
      echo "update table set " . implode(", ", array_mapk(function ($k, $v) { return "{$k} = '" . mysql_real_escape_string($v) . "'"; }, $dados));
    ?>
    Cheers.
    array_map becomes interesting and faster than foreach when used with existing PHP functions.
    Example:
    $arr1 = array(1, 2, 3, 4);
    $arr2 = array(4, 3, 2, 1);
    // array with min values for each key
    print_r(array_map("min", $arr1, $arr2));
    Result: Array ( [0] => 1 [1] => 2 [2] => 2 [3] => 1 ) 
    // array with max values for each key
    print_r(array_map("max", $arr1, $arr2));
    Result: Array ( [0] => 4 [1] => 3 [2] => 3 [3] => 4 )
    I came up with a convenient syntax for method application, particularly useful inside the array_map.
    For instance, if you want to
    array_map(function($object, $arg1) { return $object->method($arg1, "arg2"); }, $objects, $args1);
    it is possible to provide a shorthand:
    global $_; // necessary inside a function, unfortunately
    array_map($_->method($_, "arg2"), $objects, $args1);
    Here's the implementation (works with 5.3)
    function m_caller($method) {
     $args = func_get_args();
     array_shift($args);
     return function($object) use($method, $args) {
      global $_;
      $local_args = func_get_args();
      array_shift($args);
      if(!is_object($object)) {
       // error                                                                                                 
      }
      $reflection = new ReflectionMethod(get_class($object), $method);
      foreach($args as $key => $arg) {
       if($arg === $_) {
        $args[$key] = array_shift($local_args);
       }
      }
      return $reflection->invokeArgs($object, array_merge($args, $local_args));
     };
    }
    class MethodCaller {
     public function __call($name, $arguments) { return call_user_func_array('m_caller', array_merge(array($name), $arguments)); }
     public function __get($name) { return m_caller($name); }
    };
    $_ = new MethodCaller();
    array_map becomes interesting and faster than foreach when used with existing PHP functions.
    Example:
    $arr1 = array(1, 2, 3, 4);
    $arr2 = array(4, 3, 2, 1);
    // array with min values for each key
    print_r(array_map("min", $arr1, $arr2));
    Result: Array ( [0] => 1 [1] => 2 [2] => 2 [3] => 1 ) 
    // array with max values for each key
    print_r(array_map("max", $arr1, $arr2));
    Result: Array ( [0] => 4 [1] => 3 [2] => 3 [3] => 4 )
    Fixed a bug with array recursion.
    <?php
        /**
         * arrayMap function. Customized array_map function which preserves keys/associate array indexes. Note that this costs a descent amount more memory (eg. 1.5k per call)
         * 
         * @access public
         * @param callback $callback Callback function to run for each element in each array.
         * @param mixed $arr1 An array to run through the callback function.
         * @param array $array Variable list of array arugments to run through the callback function.
         * @return array Array containing all the elements of $arr1 after applying the callback function to each one, recursively, maintain keys.
         */
        function arrayMap($callback,$arr1) {
          $results    =  array();
          $args     =  array();
          if(func_num_args()>2)
            $args     =  (array) array_shift(array_slice(func_get_args(),2));
          foreach($arr1 as $key=>$value) {
            $temp  =  $args;
            array_unshift($temp,$value);
            if(is_array($value)) {
              array_unshift($temp,$callback);
              $results[$key]  =  call_user_func_array(array('self','arrayMap'),$temp);
            } else {
              $results[$key]  =  call_user_func_array($callback,$temp);
            }
          }
          return $results;
        }
    ?>
    
    Could also use things like... 
    array_keys(); and array_values(); offcourse...
    However it's just an example off recursion via this function..
    Which I found pretty handy at times dealing with arrays..
    could also use:
    <?php
    call_user_func(array($this, __FUNCTION), $args);
    ?>
    or 
    <?php
    call_user_fuc_array(array($this, __FUNCTION__), $array);
    ?>
    or
    <?php
    class{
      public function __construct($arg){
        if(is_array($arg)){
          new self($arg);
        }
        else{
          echo $arg.'<br/>'.PHP_EOL;
        }
      }
    }
    ?>
    Anyway.. plenty off examples..
    It was just an idea for others...