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"
}

1voto

Koala Yeung Points 546

Je ferais quelque chose comme ça :

<?php

/**
 * array_map_kv()
 *   An array mapping function to map with both keys and values.
 *
 * @param $callback callable
 *   A callback function($key, $value) for mapping values.
 * @param $array array
 *   An array for mapping.
 */
function array_map_kv(callable $callback, array $array) {
  return array_map(
    function ($key) use ($callback, $array) {
      return $callback($key, $array[$key]); // $callback($key, $value)
    },
    array_keys($array)
  );
}

// use it
var_dump(array_map_kv(function ($key, $value) {
  return "{$key} loves {$value}";
}, array(
  "first_key" => "first_value",
  "second_key" => "second_value",
)));

?>

Résultats :

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

1voto

Minwork Points 488

Vous pouvez utiliser carte de cette méthode bibliothèque de tableaux pour atteindre exactement ce que vous voulez aussi facilement que :

Arr::map($test_array, function($a, $b) { return "$a loves $b"; });

De plus, il préserve les clés et renvoie un nouveau tableau, sans parler des différents modes qui s'adaptent à vos besoins.

0voto

Blablaenzo Points 997

Une autre façon de procéder consiste à préserver les clés :

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

$f = function($ar) {
    return array_map(
        function($key, $val) {
            return "{$key} - {$val}";
        },
        array_keys($ar),
        $ar
    );
};

#-- WITHOUT preserving keys
$res = $f($test_array);

#-- WITH preserving keys
$res = array_combine(
    array_keys($test_array),
    $f($test_array)
);

-2voto

enrey Points 848

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 :

    1. une nouvelle clé est attribuée à l'élément
    2. 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?

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