412 Stimmen

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

Ich habe ein assoziatives Array in der Form key => value wobei der Schlüssel ein numerischer Wert ist, jedoch kein fortlaufender numerischer Wert. Der Schlüssel ist eigentlich eine ID-Nummer und der Wert ist eine Zählung. Dies ist in den meisten Fällen in Ordnung, aber ich möchte eine Funktion, die den für Menschen 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 Schlüssel und den neuen Schlüssel (die ich beide habe) bereitstellen und das Array umwandeln muss. Gibt es eine effiziente Möglichkeit, dies zu tun?

0 Stimmen

17voto

Tom Ritter Punkte 97450

Sie könnten ein zweites assoziatives Array verwenden, das den Ids menschenlesbare Namen zuordnet. Das würde auch eine Viele-zu-1-Beziehung herstellen. Dann tun Sie etwas wie dies:

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

13voto

Léo Benoist Punkte 2401

Einfacher Benchmark-Vergleich der beiden Lösungen.

Lösung 1 Kopieren und entfernen (Bestellung verloren, aber viel schneller) https://stackoverflow.com/a/240676/1617857

<?php
$array = ['test' => 'value', ['etc...']];

$array['test2'] = $array['test'];
unset($array['test']);

Lösung 2 Benennen Sie den Schlüssel um https://stackoverflow.com/a/21299719/1617857

<?php
$array = ['test' => 'value', ['etc...']];

$keys = array_keys( $array );
$keys[array_search('test', $keys, true)] = 'test2';
array_combine( $keys, $array );

Benchmark:

<?php
$array = ['test' => 'value', ['etc...']];

for ($i =0; $i < 100000000; $i++){
    // Solution 1
}

for ($i =0; $i < 100000000; $i++){
    // Solution 2
}

Ergebnisse:

php solution1.php  6.33s  user 0.02s system 99% cpu 6.356  total
php solution1.php  6.37s  user 0.01s system 99% cpu 6.390  total
php solution2.php  12.14s user 0.01s system 99% cpu 12.164 total
php solution2.php  12.57s user 0.03s system 99% cpu 12.612 total

0 Stimmen

Ihr Benchmark scheint nicht korrekt zu sein. Sie ändern nur das erste Element 100 Millionen Mal, und nach dem ersten Mal werden keine Änderungen mehr vorgenommen. Ich denke, wenn der Benchmark mehrere Schlüssel ändert, wäre die zweite Lösung schneller, da die gesamte Operation auf der C++-Seite durchgeführt wird, ohne dass zwischendurch zu PHP zurückgekehrt wird.

13voto

spreadzz Punkte 260

Wenn Sie möchten, dass auch die Position des neuen Array-Schlüssels die gleiche ist wie die des alten, können Sie dies 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;
}

7voto

pajafumo Punkte 91

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

6voto

kingjeffrey Punkte 14206

Die Lösung von KernelM gefällt mir, aber ich brauchte etwas, das mit möglichen Schlüsselkonflikten umgehen kann (wenn ein neuer Schlüssel mit einem vorhandenen Schlüssel übereinstimmt). Hier ist, was ich mir ausgedacht habe:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X