it-swarm.com.de

Wie ändern Sie in PHP den Schlüssel eines Array-Elements?

Ich habe ein assoziatives Array in der Form key => value, wobei key ein numerischer Wert ist, jedoch kein sequentieller numerischer Wert. Der Schlüssel ist eigentlich eine ID-Nummer und der Wert ist eine Zählung. Dies ist für die meisten Fälle in Ordnung, jedoch möchte ich eine Funktion, die den lesbaren Namen des Arrays abruft und diesen für den Schlüssel verwendet, ohne den Wert zu ändern.

Ich habe keine Funktion gesehen, die dies tut, aber ich gehe davon aus, dass ich den alten und den neuen Schlüssel (die ich beide habe) zur Verfügung stellen und das Array transformieren muss. Gibt es einen effizienten Weg, dies zu tun?

315
Thomas Owens
$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);
495
KernelM

Auf diese Weise und unter Beibehaltung der Reihenfolge des Arrays müssen Sie die Array-Schlüssel in ein separates Array stellen. Suchen Sie den Schlüssel in diesem Array, ersetzen Sie ihn und kombinieren Sie ihn mit den Werten. 

Hier ist eine Funktion, die genau das tut:

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 );
}
78

wenn Ihre array aus einer Datenbankabfrage besteht, können Sie den Schlüssel direkt in der mysql-Anweisung ändern:

anstatt

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

verwenden Sie etwas wie:

"select ´id´ **as NEWNAME** from ´tablename´..."
46
Simon Franco

Die Antwort von KernelM ist Nizza, aber um das von Greg in dem Kommentar angesprochene Problem (in Konflikt stehende Schlüssel) zu vermeiden, wäre die Verwendung eines neuen Arrays sicherer

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

Sie könnten ein zweites assoziatives Array verwenden, das den IDs lesbare Namen zuordnet. Das würde auch eine Viele-zu-1-Beziehung ergeben. Dann machen Sie so etwas:

echo 'Widgets: ' . $data[$humanreadbleMapping['Widgets']];
15
Tom Ritter

Wenn Sie möchten, dass auch die Position des neuen Array-Schlüssels der alten entspricht, können Sie Folgendes tun:

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;
}
9
spreadzz

Hier ist eine Hilfsfunktion, um das zu erreichen:

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

ziemlich basierend auf @ KernelM answer .

Verwendungszweck:

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

Bei erfolgreicher Umbenennung wird true zurückgegeben, andernfalls false.

6
kenorb

Wenn Ihr Array rekursiv ist, können Sie diese Funktion verwenden: Testen Sie diese Daten:

    $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,
            )
    );

hier ist die Funktion:

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;   
}
6
pajafumo

Ich mag die Lösung von KernelM, aber ich brauchte etwas, das potenzielle Schlüsselkonflikte handhaben könnte (wobei ein neuer Schlüssel möglicherweise einem vorhandenen Schlüssel entspricht). Folgendes habe ich mir ausgedacht:

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

Sie können dann ein Array wie folgt durchlaufen:

$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' )
6
kingjeffrey
$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
];
*/
6
temuri

Einfache Sachen:

diese Funktion akzeptiert den Ziel-$ -Hash, und $ Ersetzungen ist auch ein Hash, der newkey => Oldkey-Assoziationen enthält.

Diese Funktion wird die ursprüngliche Reihenfolge beibehalten , kann jedoch für sehr große Arrays (wie über 10.000 Datensätze) hinsichtlich Leistung & Speicher problematisch sein.

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

diese alternative Funktion würde dasselbe tun, mit weitaus besserer Leistung & Speicherverbrauch, auf Kosten der ursprünglichen Bestellung (was kein Problem sein sollte, da es Hashtable ist!)

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;       
}
4
Nadir

dieser Code hilft, den alten Schlüssel in einen neuen zu ändern

$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);

anzeige wie

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

Es gibt eine alternative Möglichkeit, den Schlüssel eines Array-Elements zu ändern, wenn Sie mit einem vollständigen Array arbeiten - ohne die Reihenfolge des Arrays zu ändern. __ Sie müssen das Array einfach in ein neues Array kopieren.

Ich arbeitete zum Beispiel mit einem gemischten, mehrdimensionalen Array, das indizierte und assoziative Schlüssel enthielt - und ich wollte die Integer-Schlüssel durch ihre Werte ersetzen, ohne die Reihenfolge zu beeinträchtigen.

Ich habe den Schlüssel/Wert für alle numerischen Feldeinträge geändert - hier: ['0' => 'foo']. Beachten Sie, dass die Reihenfolge intakt ist.

<?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);

Ausgabe:

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

dies funktioniert zum Umbenennen des ersten Schlüssels:

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

dann gibt print_r ($ a) ein repariertes In-Order-Array aus:

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

dies funktioniert zum Umbenennen eines beliebigen Schlüssels:

$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
)

eine verallgemeinerte Funktion:

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

    return array_flip($tmp_A);
}
1
wmmso

Wenn Sie mehrere Schlüssel gleichzeitig ersetzen möchten (Reihenfolge beibehalten):

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

Verwendungszweck:

$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
lepe

Hmm, ich teste vorher nicht, aber ich denke, dass dieser Code funktioniert

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
Frank Vu

der beste Weg ist die Verwendung von Referenzen und nicht die Verwendung von unset (was einen weiteren Schritt zur Speicherbereinigung darstellt).

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

lösung:

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

sie haben ein Original und eine Referenz mit neuem Namen.

oder wenn Sie nicht möchten, dass zwei Namen in einem Wert enthalten sind, sollten Sie einen anderen Tabulator erstellen und als Referenz verwenden

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

Die Iteration ist bei Schlüsseln besser als das Klonen des gesamten Arrays und das Bereinigen des alten Arrays, wenn Sie lange Daten wie 100 Zeilen +++ usw. haben.

0

Sie können eine einfache Funktion schreiben, die den Rückruf auf die Tasten des angegebenen Arrays anwendet. Ähnlich wie 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}}

Hier ist eine Zusammenfassung https://Gist.github.com/vardius/650367e15abfb58bcd72ca47eff096ca#file-array_map_keys-php .

0
vardius

Sie können diese Funktion basierend auf array_walk verwenden:

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));

Es gibt:

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
Alekzander

Eine der Konservierungsmittelbestellungen ist einfach zu verstehen:

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
Andrew