2012-04-16 47 views
15

我怎麼能做到這一點:如何在維持順序的同時更改數組中的某個鍵?

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

我沒有看到,做一個函數。 有一種方法可以做到這一點?

回答

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

很有趣的方法,在我認爲將數組作爲參考將會更好。 – Nazariy 2012-04-16 22:45:53

+2

@Nazariy:php不會複製原始參數,直到它被修改(這就是所謂的寫時拷貝,COW)。從這個角度來看,我沒有看到在這種特殊情況下使用引用的任何優勢 – zerkms 2012-04-16 22:47:47

+0

感謝zerkms,一種優雅的方法。 – 2012-04-16 22:50:13

1

一個很好的答案已經發布,但這裏是我的兩個便士:

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

響應邁克 - 賽爾這會是一個比較公認的做法我上面的例子嗎?

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

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

我一直在尋找改善:)

+0

不應該硬編碼值imo。 – 2012-04-16 22:56:02

4

有在接受答案的邏輯缺陷。

如果你有一個這樣的數組:

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

,代之以「東西」「K4」你會得到這樣的輸出:

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

這裏是一個快速解決方案,解決了問題:

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

編輯:2014年12月3日 如果您將array_search的第三個參數(嚴格)設置爲true,則接受的答案將有效。

+1

正確,但只需在array_keys中將「strict」標誌設置爲true即可獲得所需的輸出併爲您節省8行代碼。 更改$ index = array_search($ key1,$ keys);到$ index = array_search($ key1,$ keys,true);在上面的函數產生正確的結果: [ 的 'k1'=>的 'k1', 的 'k2'=>的 'k2', 0 => 'K3', '東西'=> 'K4' ] – Cragmonkey 2014-12-01 00:06:24

+2

謝謝,你是對的。我最終也想到了這一點,但忘了這篇文章。現在就更新它。 – 2014-12-03 14:51:12

+0

只是想謝謝你...讚賞! – salih0vicX 2016-09-01 11:58:07

2

與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

使用循環的相反,你總是可以拼合到字符串json_encode(),執行字符串替換,然後json_decode()回數組:

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

現在,這並不檢查與預先存在的按鍵衝突(很容易的添加一個字符串比較校驗),它可能不適合大規模陣列單一替代的最佳解決方案..但有關陣列壓扁成替換字符串漂亮的部分是它有效地使更換遞歸,因爲在任何深度的比賽都在一個通代替:

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

輸出

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