我有一个形式为key => value
的关联数组,其中键是数字值,但它不是顺序数字值。实际上,键是一个ID号码,而值是一个计数。这在大多数情况下都很好,但是我想要一个函数,该函数获取数组的可读名称并将其用作键,而不更改值。
我没有看到可以完成此任务的函数,但我假设我需要提供旧键和新键(我都有),并转换数组。有没有一种有效的方法来实现这个?
我有一个形式为key => value
的关联数组,其中键是数字值,但它不是顺序数字值。实际上,键是一个ID号码,而值是一个计数。这在大多数情况下都很好,但是我想要一个函数,该函数获取数组的可读名称并将其用作键,而不更改值。
我没有看到可以完成此任务的函数,但我假设我需要提供旧键和新键(我都有),并转换数组。有没有一种有效的方法来实现这个?
/**
* Helper function to rename array keys.
*/
function _rename_arr_key($oldkey, $newkey, array &$arr) {
if (array_key_exists($oldkey, $arr)) {
$arr[$newkey] = $arr[$oldkey];
unset($arr[$oldkey]);
return TRUE;
} else {
return FALSE;
}
}
这篇文章基于@KernelM的回答。
用法:
_rename_arr_key('oldkey', 'newkey', $my_array);
在成功重命名时,它将返回true,否则返回false。
$i = 0;
$keys_array=array("0"=>"one","1"=>"two");
$keys = array_keys($keys_array);
for($i=0;$i<count($keys);$i++) {
$keys_array[$keys_array[$i]]=$keys_array[$i];
unset($keys_array[$i]);
}
print_r($keys_array);
$keys_array=array("one"=>"one","two"=>"two");
array_combine($keys_array, $keys_array)
。实际上,我想说的是,即使你的片段提供了所需的效果,也不应该使用它。 - mickmackusa简单的内容:
此函数将接受目标$hash,$replacements也是一个哈希,包含新键=>旧键的关联。
此函数将保留原始顺序,但对于非常大的(如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;
}
array_search()
时,不明确检查false
是有问题的。如果搜索的键是第一个元素怎么办?我担心你正在教授不可靠的做法。此外,“loosing”的正确拼写应该是“losing”。 - mickmackusareturn
/break
。这绝对不会表现良好。 - mickmackusa因为问题本身没有最小可验证示例,所以本页面充斥着广泛的解释。一些答案仅仅试图解决“标题”而不费心理解问题的要求。
关键字实际上是一个ID号码,值是一个计数。这对于大多数情况来说都很好,但我想要一个函数,它能够获取数组的可读名称,并将其用作关键字,而不改变值。
PHP关键字无法被更改,但可以被替换——这就是为什么许多答案建议使用array_search()
(性能相对较差)和unset()
的原因。
最终,您需要创建一个新数组,在原始计数相关的名称中使用关键字。这通过查找数组最有效地完成,因为查找关键字总是优于查找值。
代码: (Demo)
$idCounts = [
3 => 15,
7 => 12,
8 => 10,
9 => 4
];
$idNames = [
1 => 'Steve',
2 => 'Georgia',
3 => 'Elon',
4 => 'Fiona',
5 => 'Tim',
6 => 'Petra',
7 => 'Quentin',
8 => 'Raymond',
9 => 'Barb'
];
$result = [];
foreach ($idCounts as $id => $count) {
if (isset($idNames[$id])) {
$result[$idNames[$id]] = $count;
}
}
var_export($result);
输出:
array (
'Elon' => 15,
'Quentin' => 12,
'Raymond' => 10,
'Barb' => 4,
)
这种技术维护了原始数组顺序(如果排序很重要),不进行任何不必要的迭代,并且由于isset()
的存在,将非常迅速。
function mapToIDs($array, $id_field_name = 'id')
{
$result = [];
array_walk($array,
function(&$value, $key) use (&$result, $id_field_name)
{
$result[$value[$id_field_name]] = $value;
}
);
return $result;
}
$arr = [0 => ['id' => 'one', 'fruit' => 'apple'], 1 => ['id' => 'two', 'fruit' => 'banana']];
print_r($arr);
print_r(mapToIDs($arr));
Array(
[0] => Array(
[id] => one
[fruit] => apple
)
[1] => Array(
[id] => two
[fruit] => banana
)
)
Array(
[one] => Array(
[id] => one
[fruit] => apple
)
[two] => Array(
[id] => two
[fruit] => banana
)
)
array_column($arr, null, 'id')
。但再次强调,我必须说你的答案与这个问题无关,这个问题只处理平面数组。 - mickmackusa如果您想一次替换多个键(保留顺序):
/**
* Rename keys of an array
* @param array $array (asoc)
* @param array $replacement_keys (indexed)
* @return array
*/
function rename_keys($array, $replacement_keys) {
return array_combine($replacement_keys, array_values($array));
}
使用方法:
$myarr = array("a" => 22, "b" => 144, "c" => 43);
$newkeys = array("x","y","z");
print_r(rename_keys($myarr, $newkeys));
//must return: array("x" => 22, "y" => 144, "z" => 43);
array_combine()
不需要其参数为索引数组,因此不需要使用array_values()
。 https://3v4l.org/uN1ZF 这个答案依赖于第二个数组已经与第一个数组中的ID完全对齐。这在实际项目中很少发生,对于研究人员来说不太可能是可靠的解决方案。 - mickmackusa此函数将通过与索引搜索相结合,重命名数组键名并保留其位置。
function renameArrKey($arr, $oldKey, $newKey){
if(!isset($arr[$oldKey])) return $arr; // Failsafe
$keys = array_keys($arr);
$keys[array_search($oldKey, $keys)] = $newKey;
$newArr = array_combine($keys, $arr);
return $newArr;
}
使用方法:
$arr = renameArrKey($arr, 'old_key', 'new_key');
这个基本函数处理交换数组键并保持数组原始顺序...
public function keySwap(array $resource, array $keys)
{
$newResource = [];
foreach($resource as $k => $r){
if(array_key_exists($k,$keys)){
$newResource[$keys[$k]] = $r;
}else{
$newResource[$k] = $r;
}
}
return $newResource;
}
例如,你可以循环遍历并将所有的“a”键与“z”键交换...
$inputs = [
0 => ['a'=>'1','b'=>'2'],
1 => ['a'=>'3','b'=>'4']
]
$keySwap = ['a'=>'z'];
foreach($inputs as $k=>$i){
$inputs[$k] = $this->keySwap($i,$keySwap);
}
break
吗?这不是一个高效的解决方案。 - mickmackusa$a = ['catine' => 'cat', 'canine' => 'dog'];
$tmpa['feline'] = $a['catine'];
unset($a['catine']);
$a = $tmpa + $a;
Array
(
[feline] => cat
[canine] => dog
)
这适用于重命名任意键:
$a = ['canine' => 'dog', 'catine' => 'cat', 'porcine' => 'pig']
$af = array_flip($a)
$af['cat'] = 'feline';
$a = array_flip($af)
print_r($a)
Array
(
[canine] => dog
[feline] => cat
[porcine] => pig
)
function renameKey($oldkey, $newkey, $array) {
$val = $array[$oldkey];
$tmp_A = array_flip($array);
$tmp_A[$val] = $newkey;
return array_flip($tmp_A);
}
<?php
$arr = [
'foo',
'bar'=>'alfa',
'baz'=>['a'=>'hello', 'b'=>'world'],
];
foreach($arr as $k=>$v) {
$kk = is_numeric($k) ? $v : $k;
$vv = is_numeric($k) ? null : $v;
$arr2[$kk] = $vv;
}
print_r($arr2);
输出:
Array (
[foo] =>
[bar] => alfa
[baz] => Array (
[a] => hello
[b] => world
)
)