2012-04-16 12 views

Odpowiedz

26

http://ideone.com/nCZnY

$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array 

// rename $array['d'] as $array['b'] 
$array = replace_key_function($array, 'd', 'b'); 

var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order! 

function replace_key_function($array, $key1, $key2) 
{ 
    $keys = array_keys($array); 
    $index = array_search($key1, $keys); 

    if ($index !== false) { 
     $keys[$index] = $key2; 
     $array = array_combine($keys, $array); 
    } 

    return $array; 
} 
+0

dość ciekawe podejście, moim opinia, że ​​lepiej przekazać tablicę jako odniesienie. – Nazariy

+2

@Nazariy: php nie skopiowałby oryginalnego parametru, dopóki nie zostanie zmodyfikowany (to się nazywa kopiowanie przy zapisie, COW). Z tego punktu widzenia nie widzę żadnych zalet korzystania z referencji w tym konkretnym przypadku. – zerkms

+0

Dzięki zerkms, eleganckie podejście. –

1

dobra odpowiedź została wysłana, ale oto moje dwa pensy:

$array = array('a'=>1, 'd'=>2, 'c'=>3); 
// rename 'd' to 'b' 
foreach($array as $k=>$v){ 
    if($k == 'd') { $k='b'; } 
     $newarray[$k] = $v; 
} 
$array = $newarray; 

w odpowiedzi na mike-Purcell byłoby to bardziej akceptowane podejście do mojego powyższego przykładu?

changeKey($array, 'd', 'b'); 

function changeKey($array, $oldKey, $newKey) 
{ 
    foreach($array as $k=>$v){ 
     if($k == $oldKey) { $k = $newKey; } 
     $returnArray[$k] = $v; 
    } 
    return $returnArray; 
} 

Zawsze szukam poprawić :)

+0

Nie należy przyjmować wartości sztywnych imo. –

4

Jest to wada w logikę akceptowanych odpowiedź.

Jeśli masz tablicę takiego:

[ 
    'k1'=>'k1', 
    'k2'=>'k2', 
    'k3', 
    'k4'=>'k4' 
] 

i zastąpić „K4” z „coś” dostaniesz wyjście tak:

[ 
    'k1'=>'k1', 
    'k2'=>'k2', 
    'something' => 'k3', 
    'k4'=>'k4' 
] 

Oto szybki fix, który rozwiązuje problem:

function replace_key_function($array, $key1, $key2) 
{ 
    $keys = array_keys($array); 
    //$index = array_search($key1, $keys);   
    $index = false; 
    $i = 0; 
    foreach($array as $k => $v){ 
     if($key1 === $k){ 
      $index = $i; 
      break; 
     } 
     $i++; 
    } 

    if ($index !== false) { 
     $keys[$index] = $key2; 
     $array = array_combine($keys, $array); 
    } 

    return $array; 
} 

EDIT: 03.12.2014 Przyjęta odpowiedź zadziała, jeśli ustawisz trzeci parametr (strict) dla array_search na true.

+1

Prawidłowo, ale po prostu ustawienie flagi "ścisłe" na wartość true w array_keys dostarczy ci pożądanych wyników i zaoszczędzi 8 linii kodu. Zmiana $ index = array_search ($ key1, $ keys); do $ index = array_search ($ key1, $ keys, true); w powyższej czynności generuje poprawny wynik: [ 'k1' => 'k1', 'k2' => 'K2', 0 => 'K3, 'co'=> 'k4' ] – Cragmonkey

+2

Dzięki, masz rację. W końcu też to rozgryzłem, ale zapomniałem o tym poście. Zaktualizuje to teraz. –

+0

Chciałem ci tylko podziękować za to ... Docenione! – salih0vicX

2

ogólnym i proste rozwiązanie z użyciem PHP 5.3+ array_walk:

$array = array('a' => 1, 'd' => 2, 'c' => 3); //associative array 

$array = replace_keys($array, array('d' => 'b')); 
var_export($array); // array('a' => 1, 'b' => 2, 'c' => 3); same order! 

function replace_keys(array $source, array $keyMapping) { 
    $target = array(); 
    array_walk($source, 
       function ($v, $k, $keyMapping) use (&$target) { 
        $mappedKey = isset($keyMapping[$k]) ? $keyMapping[$k] : $k; 
        $target[$mappedKey] = $v; 
       }, 
       $keyMapping); 
    return $target; 
} 
3

Zamiast pętli, zawsze można spłaszczyć do łańcucha z json_encode(), przeprowadzić wymianę strun, następnie json_decode() powrotem do tablicy:

function replaceKey($array, $old, $new) 
{ 
    //flatten the array into a JSON string 
    $str = json_encode($array); 

    // do a simple string replace. 
    // variables are wrapped in quotes to ensure only exact match replacements 
    // colon after the closing quote will ensure only keys are targeted 
    $str = str_replace('"'.$old.'":','"'.$new.'":',$str); 

    // restore JSON string to array 
    return json_decode($str, TRUE);  
} 

Teraz nie sprawdza się konfliktów z wcześniej istniejącymi kluczami (wystarczająco łatwe, aby dodać sprawdzanie porównania ciągów), i może nie być najlepszym rozwiązaniem dla pojedynczych zamienników w masywnych tablicach .. ale ładny część o spłaszczenie tablicę na ciąg znaków do zastąpienia jest to, że skutecznie sprawia zastępczy rekurencyjnych od mecze na każdej głębokości są zastąpione w jednym przebiegu:

$arr = array(
    array(
     'name'  => 'Steve' 
     ,'city'  => 'Los Angeles' 
     ,'state' => 'CA' 
     ,'country' => 'USA' 
     ,'mother' => array(
      'name'  => 'Jessica' 
      ,'city'  => 'San Diego' 
      ,'state' => 'CA' 
      ,'country' => 'USA' 
     ) 
    ) 
    ,array(
     'name'  => 'Sara' 
     ,'city'  => 'Seattle' 
     ,'state' => 'WA' 
     ,'country' => 'USA' 
     ,'father' => array(
      'name'  => 'Eric' 
      ,'city'  => 'Atlanta' 
      ,'state' => 'GA' 
      ,'country' => 'USA' 
      ,'mother' => array(
       'name'  => 'Sharon' 
       ,'city'  => 'Portland' 
       ,'state' => 'OR' 
       ,'country' => 'USA' 
      ) 
     ) 
    ) 
); 
$replaced = replaceKey($arr,'city','town'); 
print_r($replaced); 

wyjść

Array 
(
    [0] => Array 
     (
      [name] => Steve 
      [town] => Los Angeles 
      [state] => CA 
      [country] => USA 
      [mother] => Array 
       (
        [name] => Jessica 
        [town] => San Diego 
        [state] => CA 
        [country] => USA 
       ) 
     ) 

    [1] => Array 
     (
      [name] => Sara 
      [town] => Seattle 
      [state] => WA 
      [country] => USA 
      [father] => Array 
       (
        [name] => Eric 
        [town] => Atlanta 
        [state] => GA 
        [country] => USA 
        [mother] => Array 
         (
          [name] => Sharon 
          [town] => Portland 
          [state] => OR 
          [country] => USA 
         ) 
       ) 
     ) 
) 
Powiązane problemy