311 votes

Accéder aux clés de premier niveau avec array_map() sans appeler `array_keys()`

Existe-t-il un moyen de faire quelque chose de ce genre ?

$test_array = array(
    "first_key" => "first_value", 
    "second_key" => "second_value"
);

var_dump(
    array_map(
        function($a, $b) {
            return "$a loves $b";
        }, 
        array_keys($test_array), 
        array_values($test_array)
    )
);

Mais au lieu d'appeler array_keys y array_values en transmettant directement le $test_array variable ?

Le résultat souhaité est le suivant :

array(2) {
  [0]=>
  string(27) "first_key loves first_value"
  [1]=>
  string(29) "second_key loves second_value"
}

8voto

Francesco D.M. Points 1686

Je vais ajouter une autre solution au problème en utilisant la version 5.6 ou plus. Je ne sais pas si c'est plus efficace que les solutions déjà excellentes (probablement pas), mais pour moi c'est juste plus simple à lire :

$myArray = [
    "key0" => 0,
    "key1" => 1,
    "key2" => 2
];

array_combine(
    array_keys($myArray),
    array_map(
        function ($intVal) {
            return strval($intVal);
        },
        $myArray
    )
);

Utilisation strval() comme exemple de fonction dans le array_map , ce qui génèrera :

array(3) {
  ["key0"]=>
  string(1) "0"
  ["key1"]=>
  string(1) "1"
  ["key2"]=>
  string(1) "2"
}

J'espère ne pas être le seul à trouver cela assez simple à comprendre. array_combine crée un key => value à partir d'un tableau de clés et d'un tableau de valeurs, le reste est assez explicite.

6voto

IanS Points 721

Regardez ici ! Il y a une solution triviale !

function array_map2(callable $f, array $a)
{
    return array_map($f, array_keys($a), $a);
}

Comme indiqué dans la question, array_map possède déjà exactement la fonctionnalité requise . Les autres réponses ici compliquent sérieusement les choses : array_walk n'est pas fonctionnel.

Utilisation

Exactement ce que vous attendez de votre exemple :

$test_array = array("first_key" => "first_value", 
                    "second_key" => "second_value");

var_dump(array_map2(function($a, $b) { return "$a loves $b"; }, $test_array));

3voto

ryanve Points 6881

Par "boucle manuelle", j'entends écrire une fonction personnalisée qui utilise foreach . Cela renvoie un nouveau tableau comme array_map parce que le champ d'application de la fonction entraîne une $array pour être une copie et non une référence :

function map($array, callable $fn) {
  foreach ($array as $k => &$v) $v = call_user_func($fn, $k, $v);
  return $array;
}

Votre technique utilisant array_map con array_keys bien qu'il semble plus simple et plus puissant car vous pouvez utiliser la fonction null en tant que rappel pour renvoyer les paires clé-valeur :

function map($array, callable $fn = null) {
  return array_map($fn, array_keys($array), $array);
}

3voto

Jijo Points 61

Voici comment j'ai mis cela en œuvre dans mon projet.

function array_map_associative(callable $callback, $array) {
    /* map original array keys, and call $callable with $key and value of $key from original array. */
    return array_map(function($key) use ($callback, $array){
        return $callback($key, $array[$key]);
    }, array_keys($array));
}

3voto

J.Money Points 1997

A fermeture peut fonctionner si vous n'en avez besoin qu'une seule fois. J'utiliserais un générateur .

$test_array = [
    "first_key" => "first_value", 
    "second_key" => "second_value",
];

$x_result = (function(array $arr) {
    foreach ($arr as $key => $value) {
        yield "$key loves $value";
    }
})($test_array);

var_dump(iterator_to_array($x_result));

// array(2) {
//   [0]=>
//   string(27) "first_key loves first_value"
//   [1]=>
//   string(29) "second_key loves second_value"
// }

Pour quelque chose de réutilisable :

function xmap(callable $cb, array $arr)
{
    foreach ($arr as $key => $value) {
        yield $cb($key, $value);
    }
}

var_dump(iterator_to_array(
    xmap(function($a, $b) { return "$a loves $b"; }, $test_array)
));

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X