как изменить ключ в массиве при сохранении порядка?

Как я могу это сделать:

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

Я не видел функцию, которая это делает. Есть способ сделать это?

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

В логике принятого ответа есть недостаток.

Если у вас есть такой массив:

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

EDIT: 2014/12/03 Принятый ответ работает, если вы установите для третьего параметра (strict) array_search значение true.

Вместо использования циклов вы всегда можете сгладить строку с помощью 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 ) ) ) ) 

Общее и простое решение с 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; } 

хороший ответ был опубликован, но вот мои два пенсов:

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

в ответ на mike-purcell это было бы более приемлемым подходом к моему примеру выше?

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

Я всегда стараюсь улучшить 🙂