En PHP, comment changer la clé d'un élément de tableau?

j'ai un tableau associatif dans le formulaire key => value où la clé est une valeur numérique, mais ce n'est pas séquentielle valeur numérique. La clé est en fait un numéro d'identification et la valeur est un nombre. C'est très bien pour la plupart des instances, cependant je veux une fonction qui obtient le nom lisible par l'humain du tableau et utilise cela pour la clé, sans changer la valeur.

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

307
demandé sur Thomas Owens 2008-10-27 20:09:48

18 réponses

$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);
475
répondu KernelM 2008-10-27 17:12:45

La façon de faire et de préserver l'ordre du tableau est en mettant les clés du tableau dans un tableau séparé, trouver et remplacer la clé de ce tableau et de les combiner avec les valeurs.

Voici une fonction qui fait justement 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 );
}
75
répondu DiverseAndRemote.com 2016-12-15 17:10:12

si votre array est construit à partir d'une requête de base de données, vous pouvez changer la clé directement à partir de la mysql déclaration:

au lieu de

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

utilisez quelque chose comme:

"select ´id´ **as NEWNAME** from ´tablename´..."
47
répondu Simon Franco 2014-09-29 09:49:34

la réponse de KernelM est bonne, mais pour éviter la question soulevée par Greg dans le commentaire (touches contradictoires), l'utilisation d'un nouveau tableau serait plus sûr

$newarr[$newkey] = $oldarr[$oldkey];
$oldarr=$newarr;
unset($newarr);
17
répondu kjg 2010-12-26 07:03:14

vous pouvez utiliser un second tableau associatif qui établit une correspondance entre les noms lisibles par l'homme et les id. Cela fournirait aussi une relation de plusieurs à un. Alors faites quelque chose comme ceci:

echo 'Widgets: ' . $data[$humanreadbleMapping['Widgets']];
16
répondu Tom Ritter 2008-10-27 17:12:05

si vous voulez aussi que la position de la touche new array soit la même que l'ancienne, vous pouvez faire ceci:

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;
}
10
répondu spreadzz 2015-01-27 10:43:41

Si votre tableau est récursive vous pouvez utiliser cette fonction: tester cette donnée:

    $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;   
}
7
répondu pajafumo 2012-10-25 05:16:47

j'aime la solution de KernelM, mais j'ai besoin de quelque chose qui pourrait gérer les conflits de clés potentiels (où une nouvelle clé peut correspondre à une clé existante). Voici ce que j'ai trouvé:

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 alors faire un cycle à travers 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' )
7
répondu kingjeffrey 2017-08-10 05:40:41

Voici une fonction d'aide pour réaliser cela:

/**
 * 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;
    }
}

assez basé sur @KernelM réponse .

Utilisation:

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

Il sera de retour vrai sur le succès de la renommer, sinon false .

6
répondu kenorb 2017-08-10 05:42:08

de choses simples:

cette fonction accepte le $hash cible et $replacements est aussi un hash contenant newkey=>associations oldkey .

cette fonction va préserver l'ordre original , mais pourrait être problématique pour de très grands (comme au-dessus des enregistrements 10k) tableaux concernant performance & memory .

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 la même chose, avec bien meilleure performance & utilisation de la mémoire, au prix de perdre l'ordre original (qui ne devrait pas être un problème car il est hashtable!)

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;       
}
5
répondu Nadir 2015-07-20 04:45:48
$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
];
*/
5
répondu temuri 2016-04-05 19:57:40

ce code aidera à changer l'ancienne clé en 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");
5
répondu karthikeyan ganesan 2017-08-10 05:41:29

cela fonctionne pour renommer la première clé:

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

ensuite, print_r ($a) rend un tableau d'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);
}
1
répondu wmmso 2016-05-15 21:45:12

si vous voulez remplacer plusieurs touches à la fois (en conservant 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);
1
répondu lepe 2016-07-13 02:11:34

il y a une autre façon de changer la clé d'un élément de tableau en travaillant avec un tableau complet - sans changer l'ordre du tableau. C'est tout simplement de copier le tableau dans un nouveau tableau.

par exemple, je travaillais avec un tableau mixte, multidimensionnel qui contenait des clés indexées et associatives-et je voulais remplacer les clés entières par leurs valeurs, sans briser l'ordre.

Je l'ai fait en changeant la clé / valeur pour tous entrées de Tableau Numérique-ici: ['0' = > 'foo']. Notez que la commande est intact.

<?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
        )
)
1
répondu Kristoffer Bohmann 2017-03-28 05:31:44

Hmm, je ne suis pas un test avant, 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);
}
0
répondu TungVN 2017-01-16 03:52:21

un que les conservateurs ordonnent qui 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;
}
0
répondu Andrew 2018-08-15 10:55:31

vous pouvez utiliser cette fonction basée 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));

il 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
    )
)
0
répondu Alekzander 2018-09-09 20:08:33