I'm proposing a new function similar to the implementation of array_map that allows us to apply a user-supplied callback to every element in the array with the addition of the callback being passed the key as well as the value of each element. Additionally, I would like to propose that the callback can modify both the key as well as the value by return an array where the key would be used to replace the existing key and the value would replace the existing value.
Currently, getting the key into the callback is only possible with array_map by passing in a second array. Modifying both values (or applying the return value of the callback to both the key and the value) is not possible with array_map. Modifying the existing behavior of the function would cause BC breaks since there are probably a lot of people using code similar to the following: array_map('strlen', array('foo','bar','baz','quix')); Where strlen expects exactly one parameter and handing two arguments would cause it to implicitly return null and issue an E_WARNING with each iteration of array_map. To get both the key and the value into the callback you would have to do something like the following: array_map('my_callback', $array, array_keys($array)); Unfortunately, this has some performance and memory implications. PHP arrays carry a lot of overhead and a large enough array means we hand a copy of they array keys as an array to the function. This may be unnecessary with a slightly improved implementation. So instead we would have to have a new function like array_map_key (perhaps) that passes two arguments to the callback on each iteration (the key and the value of each element). This would make the following code possible... function my_call_back($key, $value) { return array($value, strlen($value)); } $array = str_word_count("PHP is lots of fun!"); $array = array_map_key('my_call_back', $array); The result would be the following array: array(5) { ["PHP"]=> int(3) ["is"]=> int(2) ["lots"]=> int(4) ["of"]=> int(2) ["fun"]=> int(3) } This demonstrates modifying both the key as well as the value by applying a user supplied callback function to each of the array's elements. This can also be done with the foreach construct, but the problem with foreach constructs is that they are not reusable. Since array_map takes a callback it's easy to reuse the callback function in various places to modify similar data structures. This is not so with foreach. It can be argued that we simply put the foreach loop into a function and reuse that, but there is a slight performance optimization with the implementation of array_map that foreach can't do and that's that array_map can iterate over all of the arrays supplied at once and more quickly than user space can do the iteration. It wouldn't be too hard to modify the implementation of array_map ( http://lxr.php.net/xref/PHP_5_5/ext/standard/array.c#4270) to pass in the key and be able to return a new array where both key/value pairs are applied by the callback given the existing implementation already accesses this information with each iteration (so there's no noticeable performance degradation). The only change would be in constructing the new return value to include the key from the return value instead of using the existing key. I would like to get everyone's thoughts on introducing such a function into PHP 5.NEXT (obviously I'm too late for 5.5). If there is a real need for this function out there and I'm not the only one that thinks this is useful I would be happy to draft an RFC and provide an implementation. Regards, Sherif I don't just make coffee around the office. Sometimes they let me write code!