web-dev-qa-db-fra.com

changer les clés du tableau dans la fonction array_walk?

J'utilise des fonctions de tableau pour convertir ma chaîne délimitée par un tuyau en un tableau associatif.

$piper = "|k=f|p=t|e=r|t=m|";

$piper = explode("|",$piper);

$piper = array_filter($piper);

function splitter(&$value,$key) {

    $splitted = explode("=",$value);
    $key = $splitted[0];
    $value = $splitted[1];

}

array_walk($piper, 'splitter');

var_dump($piper);

cela me donne 

array (size=4)
  1 => string 'f' (length=1)
  2 => string 't' (length=1)
  3 => string 'r' (length=1)
  4 => string 'm' (length=1)

où je veux:

array (size=4)
  "k" => string 'f' (length=1)
  "p" => string 't' (length=1)
  "e" => string 'r' (length=1)
  "t" => string 'm' (length=1)

mais les clés sont inchangées. Existe-t-il une fonction de tableau avec laquelle je peux parcourir un tableau et modifier les clés et les valeurs?

23
mithunsatheesh

C'est dit dans la documentation de array_walk (décrivant la fonction de rappel):

Seules les valeurs du tableau peuvent potentiellement être modifiées. sa structure ne peut pas être modifié, c’est-à-dire que le programmeur ne peut pas ajouter, annuler ou réorganiser éléments. Si le rappel ne respecte pas cette exigence, le le comportement de cette fonction est indéfini et imprévisible.

Cela signifie que vous ne pouvez pas utiliser array_walk pour modifier les clés du tableau itéré. Vous pouvez cependant créer un nouveau tableau avec:

$result = array();
array_walk($piper, function (&$value,$key) use (&$result) {
    $splitted = explode("=",$value);
    $result[ $splitted[0] ] = $splitted[1];
});
var_dump($result);

Pourtant, je pense que si c'était moi, j'utiliserais regex ici (au lieu de "exploser l'explosé"):

$piper = "|k=f|p=t|e=r|t=m|";
preg_match_all('#([^=|]*)=([^|]*)#', $piper, $matches, PREG_PATTERN_ORDER);
$piper = array_combine($matches[1], $matches[2]);
var_dump($piper);
53
raina77ow

Vous pouvez mieux utiliser foreach pour cela. L'exemple suivant montre le traitement d'une entrée, l'ajoutant avec la bonne clé et la suppression de l'entrée d'origine.

$piper = "|k=f|p=t|e=r|t=m|";
$piper = array_filter(explode("|", $piper));

foreach ($piper as $index => $value) {
    list($key, $value) = explode("=", $value);
    $piper[$key] = $value;
    unset($piper[$index]);
}

Veillez à ne pas avoir de clés qui ressemblent à un index.

Une autre alternative consiste à traiter les valeurs via une référence, puis à définir les clés:

foreach ($piper as &$value) {
    list($keys[], $value) = explode("=", $value);
}
unset($value);

$piper = array_combine($keys, $piper);

Cela ne vous pose aucun problème, mais uniquement avec des clés en double. Mais vous pourriez vérifier ce problème après la foreach, aucune donnée ne serait perdue.

Quelque chose qui ne peut pas être garanti avec la foreach suivante qui est probablement la plus simplifiée en glissant dans un tableau de résultats:

$result = array();
foreach ($piper as $value) {
    list($key, $value) = explode("=", $value);
    $result[$key] = $value;
}
3
hakre

Pourquoi ne pas construire un nouveau tableau contenant les clés et les valeurs souhaitées de $ piper?

$piper2 = array();
foreach ($piper as $k => $val)
{
  $splitted = explode("=", $val);
  $key = $splitted[0];
  $value = $splitted[1];

  $piper2[$key] = $value;
}

$piper = $piper2; // if needed
3
user1703809

Utiliser array_reduce fera l'affaire

$piper = "|k=f|p=t|e=r|t=m|";

$piper = explode("|",$piper);

$piper = array_filter($piper);

function splitter($result, $item) {
    $splitted = explode("=",$item);
    $key = $splitted[0];
    $value = $splitted[1];

    $result[$key] = $value;

    return $result;
}

$piper = array_reduce($piper, 'splitter', array());

var_dump($piper);

sur cette base: http://www.danielauener.com/howto-use-array_map-on-associative-arrays-to-change-values-and-keys/

0
B. Assem