Je vois qu'il manque la réponse évidente :
function array_map_assoc(){
if(func_num_args() < 2) throw new \BadFuncionCallException('Missing parameters');
$args = func_get_args();
$callback = $args[0];
if(!is_callable($callback)) throw new \InvalidArgumentException('First parameter musst be callable');
$arrays = array_slice($args, 1);
array_walk($arrays, function(&$a){
$a = (array)$a;
reset($a);
});
$results = array();
$max_length = max(array_map('count', $arrays));
$arrays = array_map(function($pole) use ($max_length){
return array_pad($pole, $max_length, null);
}, $arrays);
for($i=0; $i < $max_length; $i++){
$elements = array();
foreach($arrays as &$v){
$elements[] = each($v);
}
unset($v);
$out = call_user_func_array($callback, $elements);
if($out === null) continue;
$val = isset($out[1]) ? $out[1] : null;
if(isset($out[0])){
$results[$out[0]] = $val;
}else{
$results[] = $val;
}
}
return $results;
}
Fonctionne exactement comme array_map. Presque.
En fait, il n'est pas pur map
tel que vous le connaissez dans d'autres langues. Php est très bizarre, il nécessite donc des fonctions utilisateur très bizarres, car nous ne voulons pas casser nos fonctions précisément cassées. worse is better
l'approche.
En réalité, ce n'est pas le cas map
du tout. Il n'en reste pas moins très utile.
-
La première différence évidente avec array_map est que le callback prend les sorties de each()
à partir de chaque tableau d'entrée au lieu de la valeur seule. Il est toujours possible d'itérer sur plusieurs tableaux à la fois.
-
La deuxième différence est la manière dont la clé est gérée après avoir été renvoyée par la fonction de rappel ; la valeur de retour de la fonction de rappel doit être array('new_key', 'new_value')
. Les clés peuvent être et seront modifiées, les mêmes clés peuvent même entraîner l'écrasement de la valeur précédente, si la même clé a été renvoyée. Ce n'est pas courant map
tout en permettant de réécrire les clés.
-
Troisièmement, si vous omettez key
dans la valeur de retour (soit par array(1 => 'value')
o array(null, 'value')
), une nouvelle clé va être attribuée, comme si $array[] = $value
a été utilisé. Ce n'est pas map
Il s'agit là d'un comportement courant, mais qui peut s'avérer utile parfois.
-
La quatrième chose étrange est que si la fonction de rappel ne renvoie pas de valeur, ou renvoie null
l'ensemble des clés et des valeurs actuelles est omis de la sortie, il est simplement ignoré. Cette fonctionnalité n'est pas du tout map
de la fonction, mais il ferait de cette fonction une excellente doublure de cascadeur pour array_filter_assoc
s'il existe une telle fonction.
-
Si vous omettez le deuxième élément ( 1 => ...
) (le valeur ) dans le retour du callback, null
est utilisé à la place de la valeur réelle.
-
Tous les autres éléments, à l'exception de ceux dont la clé est 0
y 1
dans le retour du callback sont ignorés.
-
Enfin, si lambda renvoie une valeur autre que null
ou un tableau, il est traité comme si la clé et la valeur étaient omises, donc :
- une nouvelle clé est attribuée à l'élément
null
est utilisé comme valeur
AVERTISSEMENT :
Gardez à l'esprit que cette dernière fonction n'est qu'un résidu des fonctions précédentes et qu'elle est probablement totalement inutile. Il est fortement déconseillé de s'appuyer sur cette fonction, car elle sera aléatoirement utilisée dans le cadre de l'application de la loi. obsolète et modifié de manière inattendue dans les versions ultérieures.
NOTE :
Contrairement à ce qui se passe en array_map
tous les paramètres autres que les tableaux passés à array_map_assoc
à l'exception du premier paramètre de rappel, sont silencieusement convertis en tableaux.
EXEMPLES :
// TODO: examples, anyone?