我有一个形式key =>值的关联数组,其中key是一个数值,但它不是一个连续的数值。键实际上是一个ID号,值是一个计数。这对于大多数实例来说都很好,但是我想要一个函数获得人类可读的数组名称并将其用作键,而不更改值。
我没有看到这样做的函数,但我假设我需要提供旧键和新键(我都有)并转换数组。有没有一种有效的方法来做到这一点?
我有一个形式key =>值的关联数组,其中key是一个数值,但它不是一个连续的数值。键实际上是一个ID号,值是一个计数。这对于大多数实例来说都很好,但是我想要一个函数获得人类可读的数组名称并将其用作键,而不更改值。
我没有看到这样做的函数,但我假设我需要提供旧键和新键(我都有)并转换数组。有没有一种有效的方法来做到这一点?
当前回答
嗯,我没有测试之前,但我认为这段代码工作
function replace_array_key($data) {
$mapping = [
'old_key_1' => 'new_key_1',
'old_key_2' => 'new_key_2',
];
$data = json_encode($data);
foreach ($mapping as $needed => $replace) {
$data = str_replace('"'.$needed.'":', '"'.$replace.'":', $data);
}
return json_decode($data, true);
}
其他回答
简单的东西:
此函数将接受目标$哈希值,$replacement也是包含newkey=>oldkey关联的哈希值。
这个函数将保留原始顺序,但对于非常大的数组(比如超过10k的记录),在性能和内存方面可能会有问题。
function keyRename(array $hash, array $replacements) {
$new=array();
foreach($hash as $k=>$v)
{
if($ok=array_search($k,$replacements))
$k=$ok;
$new[$k]=$v;
}
return $new;
}
这个替代函数也会做同样的事情,具有更好的性能和内存使用,代价是失去原来的顺序(这应该不是问题,因为它是哈希表!)
function keyRename(array $hash, array $replacements) {
foreach($hash as $k=>$v)
if($ok=array_search($k,$replacements))
{
$hash[$ok]=$v;
unset($hash[$k]);
}
return $hash;
}
一种简单易懂的保存秩序的方法:
function rename_array_key(array $array, $old_key, $new_key) {
if (!array_key_exists($old_key, $array)) {
return $array;
}
$new_array = [];
foreach ($array as $key => $value) {
$new_key = $old_key === $key
? $new_key
: $key;
$new_array[$new_key] = $value;
}
return $new_array;
}
如果你还想让新数组键的位置与旧数组键的位置相同,你可以这样做:
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;
}
最好的方法是使用引用,而不是使用unset(这是清理内存的另一个步骤)
$tab = ['two' => [] ];
解决方案:
$tab['newname'] = & $tab['two'];
你有一份原件和一份有新名字的参考资料。
或者如果你不想在一个值中有两个名字是很好的,让另一个TAB和foreach引用
foreach($tab as $key=> & $value) {
if($key=='two') {
$newtab["newname"] = & $tab[$key];
} else {
$newtab[$key] = & $tab[$key];
}
}
迭代键比克隆所有数组更好,如果你有长数据,如100行+++等,清洗旧数组。
两种解决方案的简单基准比较。
解决方案1复制和删除(订单丢失,但更快)https://stackoverflow.com/a/240676/1617857
<?php
$array = ['test' => 'value', ['etc...']];
$array['test2'] = $array['test'];
unset($array['test']);
解决方案2密钥重命名为“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 );
基准:
<?php
$array = ['test' => 'value', ['etc...']];
for ($i =0; $i < 100000000; $i++){
// Solution 1
}
for ($i =0; $i < 100000000; $i++){
// Solution 2
}
结果:
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