Al mapear una función anónima sobre una matriz anónima, no hay forma de acceder a las claves:
array_map(
function($val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
array_reduce tampoco tiene acceso a las claves. array_walk puede acceder a las claves, pero la matriz se pasa por referencia, lo que requiere una capa de indirección.
Algunas soluciones son:
Matriz de pares
Esto es malo, ya que estamos cambiando la matriz original. Además, las llamadas repetitivas "array ()" aumentan linealmente con la longitud de la matriz:
array_map(
function($pair) use ($foo) {
list($key, $val) = $pair;
},
array(array(key1, val1),
array(key2, val2),
));
Variable temporal
Estamos actuando sobre la matriz original, y el texto estándar es constante, pero podemos golpear fácilmente una variable existente:
$i_hope_this_does_not_conflict = array(key1 => val1,
key2 => val2,
);
array_map(
function($key, $val) use ($foo) { },
array_keys($i_hope_this_does_not_conflict),
$i_hope_this_does_not_conflict);
unset($i_hope_this_does_not_conflict);
Función de disparo único
Podemos usar el alcance de la función para evitar aplastar los nombres existentes, pero tenemos que agregar una capa adicional de "uso":
call_user_func(
function($arr) use ($foo) {
return array_map(function($key, $val) use ($foo) { },
array_keys($arr),
$arr);
},
array(key1 => val1,
key2 => val2,
));
Función one-shot de múltiples argumentos
Definimos la función que estamos mapeando en el alcance original para evitar el "uso" repetitivo):
call_user_func(
function($f, $arr) {
return array_map($f, array_keys($arr), $arr);
},
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Nueva función
Lo interesante a tener en cuenta es que nuestra última función one-shot tiene una bonita firma genérica y se parece mucho a array_map. Es posible que queramos darle un nombre y reutilizarlo:
function array_mapk($f, $arr) {
return array_map($f, array_keys($arr), $arr);
}
Nuestro código de aplicación se convierte en:
array_mapk(
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Paseo indirecto por matriz
Al escribir lo anterior, ignoré array_walk ya que requiere que su argumento se pase por referencia; sin embargo, desde entonces me di cuenta de que es fácil solucionar esto usando call_user_func. Creo que esta es la mejor versión hasta ahora:
call_user_func(
'array_walk',
array(key1 => val1,
key2 => val2,
),
function($val, $key) use ($foo) { });