Question

J'ai un tableau associatif sous la forme key = > valeur où clé est une valeur numérique, mais il ne s'agit pas d'une valeur numérique séquentielle. La clé est en fait un numéro d'identification et la valeur est un compte. C’est bien dans la plupart des cas, mais je veux une fonction qui récupère le nom du tableau, lisible par l’homme, et l’utilise pour la clé, sans changer la valeur.

Je n'ai pas vu de fonction qui fait cela, mais je suppose que je dois fournir l'ancienne clé et la nouvelle clé (les deux que j'ai) et transformer le tableau. Existe-t-il un moyen efficace de le faire?

Était-ce utile?

La solution

$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);

Autres conseils

Pour conserver cela et conserver l'ordre du tableau, vous devez placer les clés de tableau dans un tableau séparé, rechercher et remplacer la clé dans ce tableau, puis la combiner avec les valeurs.

Voici une fonction qui fait exactement cela:

function change_key( $array, $old_key, $new_key ) {

    if( ! array_key_exists( $old_key, $array ) )
        return $array;

    $keys = array_keys( $array );
    $keys[ array_search( $old_key, $keys ) ] = $new_key;

    return array_combine( $keys, $array );
}

si votre tableau est construit à partir d'une requête de base de données, vous pouvez modifier la clé directement à partir de l'instruction mysql :

au lieu de

"select ´id´ from ´tablename´..."

utilisez quelque chose comme:

"select ´id´ **as NEWNAME** from ´tablename´..."

La réponse de KernelM est bien, mais pour éviter le problème soulevé par Greg dans le commentaire (clés en conflit), l’utilisation d’un nouveau tableau serait plus sûre

$newarr[$newkey] = $oldarr[$oldkey];
$oldarr=$newarr;
unset($newarr);

Vous pouvez utiliser un second tableau associatif qui mappe les noms lisibles par l'homme aux identifiants. Cela fournirait également une relation plusieurs à un. Ensuite, faites quelque chose comme ça:

echo 'Widgets: ' . $data[$humanreadbleMapping['Widgets']];

Si vous souhaitez également que la position de la nouvelle clé de tableau soit la même que l'ancienne, procédez comme suit:

function change_array_key( $array, $old_key, $new_key) {
    if(!is_array($array)){ print 'You must enter a array as a haystack!'; exit; }
    if(!array_key_exists($old_key, $array)){
        return $array;
    }

    $key_pos = array_search($old_key, array_keys($array));
    $arr_before = array_slice($array, 0, $key_pos);
    $arr_after = array_slice($array, $key_pos + 1);
    $arr_renamed = array($new_key => $array[$old_key]);

    return $arr_before + $arr_renamed + $arr_after;
}

Si votre tableau est récursif, vous pouvez utiliser cette fonction: tester ces données:

    $datos = array
    (
        '0' => array
            (
                'no' => 1,
                'id_maquina' => 1,
                'id_transaccion' => 1276316093,
                'ultimo_cambio' => 'asdfsaf',
                'fecha_ultimo_mantenimiento' => 1275804000,
                'mecanico_ultimo_mantenimiento' =>'asdfas',
                'fecha_ultima_reparacion' => 1275804000,
                'mecanico_ultima_reparacion' => 'sadfasf',
                'fecha_siguiente_mantenimiento' => 1275804000,
                'fecha_ultima_falla' => 0,
                'total_fallas' => 0,
            ),

        '1' => array
            (
                'no' => 2,
                'id_maquina' => 2,
                'id_transaccion' => 1276494575,
                'ultimo_cambio' => 'xx',
                'fecha_ultimo_mantenimiento' => 1275372000,
                'mecanico_ultimo_mantenimiento' => 'xx',
                'fecha_ultima_reparacion' => 1275458400,
                'mecanico_ultima_reparacion' => 'xx',
                'fecha_siguiente_mantenimiento' => 1275372000,
                'fecha_ultima_falla' => 0,
                'total_fallas' => 0,
            )
    );

voici la fonction:

function changekeyname($array, $newkey, $oldkey)
{
   foreach ($array as $key => $value) 
   {
      if (is_array($value))
         $array[$key] = changekeyname($value,$newkey,$oldkey);
      else
        {
             $array[$newkey] =  $array[$oldkey];    
        }

   }
   unset($array[$oldkey]);          
   return $array;   
}
$array = [
    'old1' => 1
    'old2' => 2
];

$renameMap = [
    'old1' => 'new1',   
    'old2' => 'new2'
];

$array = array_combine(array_map(function($el) use ($renameMap) {
    return $renameMap[$el];
}, array_keys($array)), array_values($array));

/*
$array = [
    'new1' => 1
    'new2' => 2
];
*/

J'aime la solution de KernelM, mais il me fallait quelque chose qui gèrerait des conflits de clés potentiels (lorsqu'une nouvelle clé peut correspondre à une clé existante). Voici ce que je suis venu avec:

function swapKeys( &$arr, $origKey, $newKey, &$pendingKeys ) {
    if( !isset( $arr[$newKey] ) ) {
        $arr[$newKey] = $arr[$origKey];
        unset( $arr[$origKey] );
        if( isset( $pendingKeys[$origKey] ) ) {
            // recursion to handle conflicting keys with conflicting keys
            swapKeys( $arr, $pendingKeys[$origKey], $origKey, $pendingKeys );
            unset( $pendingKeys[$origKey] );
        }
    } elseif( $newKey != $origKey ) {
        $pendingKeys[$newKey] = $origKey;
    }
}

Vous pouvez ensuite parcourir un tableau comme celui-ci:

$myArray = array( '1970-01-01 00:00:01', '1970-01-01 00:01:00' );
$pendingKeys = array();
foreach( $myArray as $key => $myArrayValue ) {
    // NOTE: strtotime( '1970-01-01 00:00:01' ) = 1 (a conflicting key)
    $timestamp = strtotime( $myArrayValue );
    swapKeys( $myArray, $key, $timestamp, $pendingKeys );
}
// RESULT: $myArray == array( 1=>'1970-01-01 00:00:01', 60=>'1970-01-01 00:01:00' )

Voici une fonction d'assistance pour y parvenir:

/**
 * Helper function to rename array keys.
 */
function _rename_arr_key($oldkey, $newkey, array &$arr) {
    if (array_key_exists($oldkey, $arr)) {
        $arr[$newkey] = $arr[$oldkey];
        unset($arr[$oldkey]);
        return TRUE;
    } else {
        return FALSE;
    }
}

plutôt basé sur la réponse @KernelM .

Utilisation:

_rename_arr_key('oldkey', 'newkey', $my_array);

Il renverra true en cas de renommage réussi, sinon false .

Ce qui est facile:

cette fonction acceptera les hachages cibles $ et $ remplacements est également un hachage contenant newkey = > anciennes associations .

Cette fonction préservera l'ordre d'origine , mais pourrait poser problème pour les baies très volumineuses (comme celles de plus de 10 000 enregistrements) concernant performance & amp; mémoire .

function keyRename(array $hash, array $replacements) {
    $new=array();
    foreach($hash as $k=>$v)
    {
        if($ok=array_search($k,$replacements))
            $k=$ok;
        $new[$k]=$v;
    }
    return $new;    
}

cette fonction alternative ferait de même, avec des performances bien meilleures & amp; utilisation de la mémoire, au prix de la perte de la commande d'origine (ce qui ne devrait pas poser de problème puisqu'il s'agit d'une table de hachage!)

function keyRename(array $hash, array $replacements) {

    foreach($hash as $k=>$v)
        if($ok=array_search($k,$replacements))
        {
          $hash[$ok]=$v;
          unset($hash[$k]);
        }

    return $hash;       
}

ce code aidera à remplacer l'ancienne clé par une nouvelle

$i = 0;
$keys_array=array("0"=>"one","1"=>"two");

$keys = array_keys($keys_array);

for($i=0;$i<count($keys);$i++) {
    $keys_array[$keys_array[$i]]=$keys_array[$i];
    unset($keys_array[$i]);
}
print_r($keys_array);

afficher comme

$keys_array=array("one"=>"one","two"=>"two");

cela fonctionne pour renommer la première clé:

$a = ['catine' => 'cat', 'canine'  => 'dog'];
$tmpa['feline'] = $a['catine'];
unset($a['catine']);
$a = $tmpa + $a;

alors, print_r ($ a) restitue un tableau dans l'ordre réparé:

Array
(
    [feline] => cat
    [canine] => dog
)

cela fonctionne pour renommer une clé arbitraire:

$a = ['canine'  => 'dog', 'catine' => 'cat', 'porcine' => 'pig']
$af = array_flip($a)
$af['cat'] = 'feline';
$a = array_flip($af)

print_r ($ a)

Array
(
    [canine] => dog
    [feline] => cat
    [porcine] => pig
)

une fonction généralisée:

function renameKey($oldkey, $newkey, $array) {
    $val = $array[$oldkey];
    $tmp_A = array_flip($array);
    $tmp_A[$val] = $newkey;

    return array_flip($tmp_A);
}

Si vous souhaitez remplacer plusieurs clés à la fois (en respectant l'ordre):

/**
 * Rename keys of an array
 * @param array $array (asoc)
 * @param array $replacement_keys (indexed)
 * @return array
 */
function rename_keys($array, $replacement_keys)  {
      return array_combine($replacement_keys, array_values($array));
}

Utilisation:

$myarr = array("a" => 22, "b" => 144, "c" => 43);
$newkeys = array("x","y","z");
print_r(rename_keys($myarr, $newkeys));
//must return: array("x" => 22, "y" => 144, "z" => 43);

Il existe un autre moyen de changer la clé d'un élément de tableau lorsque vous travaillez avec un tableau complet - sans modifier l'ordre du tableau. C’est simplement pour copier le tableau dans un nouveau tableau.

Par exemple, je travaillais avec un tableau mixte multidimensionnel contenant des clés indexées et associatives - et je souhaitais remplacer les clés entières par leurs valeurs sans rompre l'ordre.

Je l’ai fait en changeant la clé / la valeur de toutes les entrées numériques du tableau - ici: ['0' = > 'foo']. Notez que la commande est intacte.

<?php
$arr = [
    'foo',
    'bar'=>'alfa',
    'baz'=>['a'=>'hello', 'b'=>'world'],
];

foreach($arr as $k=>$v) {
    $kk = is_numeric($k) ? $v : $k;
    $vv = is_numeric($k) ? null : $v;
    $arr2[$kk] = $vv;
}

print_r($arr2);

Sortie:

Array (
    [foo] => 
    [bar] => alfa
    [baz] => Array (
            [a] => hello
            [b] => world
        )
)

Vous pouvez utiliser cette fonction sur array_walk:

function mapToIDs($array, $id_field_name = 'id')
{
    $result = [];
    array_walk($array, 
        function(&$value, $key) use (&$result, $id_field_name)
        {
            $result[$value[$id_field_name]] = $value;
        }
    );
    return $result;
}

$arr = [0 => ['id' => 'one', 'fruit' => 'apple'], 1 => ['id' => 'two', 'fruit' => 'banana']];
print_r($arr);
print_r(mapToIDs($arr));

Cela donne:

Array(
    [0] => Array(
        [id] => one
        [fruit] => apple
    )
    [1] => Array(
        [id] => two
        [fruit] => banana
    )
)

Array(
    [one] => Array(
        [id] => one
        [fruit] => apple
    )
    [two] => Array(
        [id] => two
        [fruit] => banana
    )
)

Hmm, je n'ai pas encore testé, mais je pense que ce code fonctionne

function replace_array_key($data) {
    $mapping = [
        'old_key_1' => 'new_key_1',
        'old_key_2' => 'new_key_2',
    ];

    $data = json_encode($data);
    foreach ($mapping as $needed => $replace) {
        $data = str_replace('"'.$needed.'":', '"'.$replace.'":', $data);
    }

    return json_decode($data, true);
}

Celui qui préserve les commandes est simple à comprendre:

function rename_array_key(array $array, $old_key, $new_key) {
  if (!array_key_exists($old_key, $array)) {
      return $array;
  }
  $new_array = [];
  foreach ($array as $key => $value) {
    $new_key = $old_key === $key
      ? $new_key
      : $key;
    $new_array[$new_key] = $value;
  }
  return $new_array;
}

Le meilleur moyen consiste à utiliser une référence et non à utiliser un paramètre non défini (ce qui constitue une étape supplémentaire pour nettoyer la mémoire)

.
$tab = ['two' => [] ];

solution:

$tab['newname'] = & $tab['two'];

vous avez un original et une référence avec un nouveau nom.

ou si vous ne voulez pas avoir deux noms dans une valeur est bon, créez un autre onglet et foreach sur la référence

foreach($tab as $key=> & $value) {
    if($key=='two') { 
        $newtab["newname"] = & $tab[$key];
     } else {
        $newtab[$key] = & $tab[$key];
     }
}

L’itération est meilleure pour les clés que pour le clonage de tous les tableaux, et le nettoyage de l’ancien tableau si vous avez des données longues comme 100 rangées +++ etc ..

Vous pouvez écrire une fonction simple qui applique le rappel aux clés du tableau donné. Similaire à array_map

<?php
function array_map_keys(callable $callback, array $array) {
    return array_merge([], ...array_map(
        function ($key, $value) use ($callback) { return [$callback($key) => $value]; },
        array_keys($array),
        $array
    ));
}

$array = ['a' => 1, 'b' => 'test', 'c' => ['x' => 1, 'y' => 2]];
$newArray = array_map_keys(function($key) { return 'new' . ucfirst($key); }, $array);

echo json_encode($array); // {"a":1,"b":"test","c":{"x":1,"y":2}}
echo json_encode($newArray); // {"newA":1,"newB":"test","newC":{"x":1,"y":2}}

Voici un résumé https://gist.github.com/vardius / 650367e15abfb58bcd72ca47eff096ca # file-array_map_keys-php .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top