Php 如何在保持顺序的同时更改数组中的键?
我如何做到这一点:Php 如何在保持顺序的同时更改数组中的键?,php,arrays,Php,Arrays,我如何做到这一点: $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 ord
$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!
我没有看到这样的函数。
有办法做到这一点吗?
一个很好的答案已经发布,但这是我的两便士:
$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;
}
我一直在寻求改进:)公认答案的逻辑存在缺陷 如果您有这样一个数组:
[
'k1'=>'k1',
'k2'=>'k2',
'k3',
'k4'=>'k4'
]
[
'k1'=>'k1',
'k2'=>'k2',
'something' => 'k3',
'k4'=>'k4'
]
将“k4”替换为“某物”,您将得到如下输出:
[
'k1'=>'k1',
'k2'=>'k2',
'k3',
'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/03
如果您将array\u search的第三个参数(strict)设置为true,则可接受的答案确实有效。使用
array\u walk的PHP 5.3+通用且简单的解决方案:
$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;
}
您可以使用json\u encode()
,执行字符串替换,然后json\u 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
)
)
)
)
非常有趣的方法,在我看来,将数组作为引用传递会更好。@Nazary:php不会复制原始参数,直到它被修改(这称为编写时复制,COW)。从这个角度来看,我看不出在这种特殊情况下使用引用有什么好处感谢zerkms,这是一种优雅的方法。@zerkms只是想知道,我有一个数组,其中前两个索引是字符串,第三个是整数,后面的其余是字符串,你的函数还能工作吗?@Memor-X:所以,你不是在尝试,而是假设我会在你和小猫一起观看youtube视频时为你这样做?我不应该硬编码值。正确,但只要在array_key中将“strict”标志设置为true,就可以得到所需的输出,并为你节省8行代码。更改$index=array\u search($key1,$keys);to$index=array\u search($key1,$keys,true);在上面的函数中生成正确的结果:['k1'=>'k1','k2'=>'k2',0=>'k3','something'=>'k4']谢谢,你是正确的。我最终也明白了这一点,但忘记了这篇文章。现在将更新它。我只是想感谢你。。。谢谢!