|
array_map
Applies the callback to the elements of the given arrays
(PHP 4 >= 4.0.6, PHP 5)
Example 257. array_map() example<?php
This makes Array Example 258. array_map() - using more arrays<?php The above example will output: // printout of $c Example 259. Creating an array of arrays<?php The above example will output: Array Code Examples / Notes » array_mapdavid dot tulloh
You can pass values to array_map by reference, essentially allowing you to use it as you would array_walk with multiple arrays as parameters. A trivial example: <?php $a = array(1,2,3,4,5); $add_func = create_function('&$x, $y', '$x+=$y;'); array_map($add_func, $a, $a); print_r($a); ?> Array ( [0] => 2 [1] => 4 [2] => 6 [3] => 8 [4] => 10 ) vinicius cubas brand
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 ) bishop
Occasionally, you may find that you need to pull out a column (or several) from an array. Here's a map-like function to do that: <?php function &array_shear(&$arrays, $idx1 /* ... */) { $indexes = func_get_args(); array_shift($indexes); $newArrays = array (); foreach (array_keys($arrays) as $arrayKey) { $newArray = array (); foreach ($indexes as $index) { $newArray[$index] = $arrays[$arrayKey][$index]; unset($arrays[$arrayKey][$index]); } $newArrays[$arrayKey] = $newArray; } return $newArrays; } ?> So, doing this: <?php $t1 = array ( 2 => array ('a', 'b', 'c'), 1 => array ('d', 'e', 'f'), 5 => array ('g', 'h', 'i'), ); $t2 = array_shear($t1, 1, 0); ?> will result in: <?php $t1 = array ( 2 => array ( 2 => 'c', ), 1 => array ( 2 => 'f', ), 5 => array ( 2 => 'i', ), ); $t2 = array ( 2 => array ( 1 => 'b', 0 => 'a', ), 1 => array ( 1 => 'e', 0 => 'd', ), 5 => array ( 1 => 'h', 0 => 'g', ), ); ?> bturchik
Maybe this one will be useful for someone: function array_map_helper($mapper, $array) { $mapper = preg_replace('/^return (.*?);$/', '$1', trim($mapper)); $result = array(); if (preg_match('/(\(?)(.*?)\s*=>\s*(.*?)(\)?)$/', $mapper, $matches)) { list($full_found, $array_open, $left, $right, $array_close) = $matches; if ($array_open && $array_close) { $mapper = '$result[] = array' . $full_found . ';'; } else { $mapper = '$result[' . $left . '] = ' . $right . ';'; } } else { $mapper = '$result[] = ' . $mapper . ';'; } foreach ($array as $key => $value) { eval($mapper); } return $result; } should be used like: $array = array(array('foo' => 11, 'bar' => 22), array('foo' => 111, 'bar' => 222), array('foo' => 1111, 'bar' => 2222)); $mapped = array_map_helper('$value["foo"] => $value["bar"]', $array); var_dump will give array(3) { [11]=> int(22) [111]=> int(222) [1111]=> int(2222) } or $mapped = array_map_helper('$value["foo"]', $array); var_dump will give array(3) { [0]=> int(11) [1]=> int(111) [2]=> int(1111) } or $mapped = array_map_helper('$value["foo"] + $value["bar"] . " at position $key"', $array); var_dump will give array(3) { [0]=> string(16) "33 at position 0" [1]=> string(17) "333 at position 1" [2]=> string(18) "3333 at position 2" } endofyourself
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. pcdinh
Hi benjaminhill, You can apply a method of a instantiated class to array_maps as follows: class Maths { function addOne($input) { return ($input + 1); } } $maths = new Maths(); $sum = array_map(array($maths, \\\'addOne\\\'), array(1, 2)); // where $maths is the object which has been instantiated before and addOne is its method without its own parameters var_dump($sum); The code fragment will return: array 0 => 2 1 => 3 However, I love a syntax like this: $sum = array_map($maths->addOne($this), array(1, 2)); where $this should be interpreted as each values extracted from the subsequent array, which in this case is array(1, 2). This syntax reminds me of Javascript syntax. PHP\\\'s callback mechanism should be improved. 26-aug-2005 02:57
Here's a function, very helpfull to me, that allows you to map your callback on mixed args. <?php function array_smart_map($callback) { // Initialization $args = func_get_args() ; array_shift($args) ; // suppressing the callback $result = array() ; // Validating parameters foreach($args as $key => $arg) if(is_array($arg)) { // the first array found gives the size of mapping and the keys that will be used for the resulting array if(!isset($size)) { $keys = array_keys($arg) ; $size = count($arg) ; // the others arrays must have the same dimension } elseif(count($arg) != $size) { return FALSE ; } // all keys are suppressed $args[$key] = array_values($arg) ; } // doing the callback thing if(!isset($size)) // if no arrays were found, returns the result of the callback in an array $result[] = call_user_func_array($callback, $args) ; else for($i=0; $i<$size; $i++) { $column = array() ; foreach($args as $arg) $column[] = ( is_array($arg) ? $arg[$i] : $arg ) ; $result[$keys[$i]] = call_user_func_array($callback, $column) ; } return $result ; } ?> Trying with : <?php // $_GET is ?foo=bar1-bar2-bar3&bar=foo1 print_r(array_smart_map('explode', '-', $_GET)) ; ?> Returns : array( [foo] => array( 0 => bar1 1 => bar2 2 => bar3 ) [bar] => array( 1 => foo1 ) ) dan
Here is a better, more true version of a deep array_map. The only negative of this function is that the array is passed by reference, so just be aware of that. (patches welcome) <?php function array_map_deep(&$in_array, $in_func, $in_args = array(), $in_index = 1) { // fix people from messing up the index of the value if ($in_index < 1) { $in_index = 1; } foreach (array_keys($in_array) as $key) { // we need a reference, not a copy, normal foreach won't do $value =& $in_array[$key]; // we need to copy args because we are doing // manipulation on it farther down $args = $in_args; if (is_array($value)) { array_map_deep($value, $in_func, $in_args, $in_index); } else { array_splice($args, $in_index - 1, $in_index - 1, $value); $value = call_user_func_array($in_func, $args); } } return $in_array; } ?> This is a neat function because you can pass an array, a function, and an array of parameters, and finally, and index of where in the array of parameters for the callback function the contents you are mapping should get replaced. This index is human based (starts at 1), and can be used in something like a preg_replace callback, where the contents must be the 3rd index. Enjoy! nd0
array_map works also fine with create_function: <?php $a = array(1, 2, 3, 4, 5); $b = array_map(create_function('$n', 'return $n*$n*$n;'), $a); print_r($b); ?> if you want to manipulate the elements of the array, instead to on a copy, than take a look at array_walk: <?php $a = array(1, 2, 3, 4, 5); array_walk($a, create_function('&$n', '$n = $n*$n*$n;')); print_r($a); ?> The Result of both is: Array ( [0] => 1 [1] => 8 [2] => 27 [3] => 64 [4] => 125 ) henrique
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()); andref dot dias
A recursive way to handle multidimensional arrays: <?php function multidimensionalArrayMap( $func, $arr ) { $newArr = array(); foreach( $arr as $key => $value ) { $newArr[ $key ] = ( is_array( $value ) ? multidimensionalArrayMap( $func, $value ) : $func( $value ) ); } return $newArr; } ?> stephen
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. |
Change Languagearray_change_key_case array_chunk array_combine array_count_values array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_diff array_fill_keys array_fill array_filter array_flip array_intersect_assoc array_intersect_key array_intersect_uassoc array_intersect_ukey array_intersect array_key_exists array_keys array_map array_merge_recursive array_merge array_multisort array_pad array_pop array_product array_push array_rand array_reduce array_reverse array_search array_shift array_slice array_splice array_sum array_udiff_assoc array_udiff_uassoc array_udiff array_uintersect_assoc array_uintersect_uassoc array_uintersect array_unique array_unshift array_values array_walk_recursive array_walk array arsort asort compact count current each end extract in_array key krsort ksort list natcasesort natsort next pos prev range reset rsort shuffle sizeof sort uasort uksort usort |