我有一个形式key =>值的关联数组,其中key是一个数值,但它不是一个连续的数值。键实际上是一个ID号,值是一个计数。这对于大多数实例来说都很好,但是我想要一个函数获得人类可读的数组名称并将其用作键,而不更改值。

我没有看到这样做的函数,但我假设我需要提供旧键和新键(我都有)并转换数组。有没有一种有效的方法来做到这一点?


当前回答

您可以使用第二个关联数组将人类可读的名称映射到id。这也将提供多对1关系。然后这样做:

echo 'Widgets: '。美元$ data [humanreadbleMapping[“窗口小部件”]];

其他回答

两种解决方案的简单基准比较。

解决方案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

最好的方法是使用引用,而不是使用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行+++等,清洗旧数组。

这里有一个帮助函数来实现这一点:

/**
 * 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。

本页对所要求的内容进行了广泛的解释,因为问题主体中没有最小的、可验证的示例。有些答案只是试图解决“标题”,而不费心去理解问题的要求。

键实际上是一个ID号,值是一个计数。这是 大多数情况下都没问题,但是我想要一个函数 人类可读的数组名称,并使用该名称作为键,无需 更改值。

PHP键不能被更改,但可以被替换——这就是为什么这么多答案建议使用array_search()(一个相对较差的性能)和unset()。

最终,您希望创建一个新数组,其名称作为与原始计数相关的键。这是通过查找数组最有效地完成的,因为搜索键总是比搜索值更好。

代码:(演示)

$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()的存在,速度非常快。

简单的东西:

此函数将接受目标$哈希值,$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;       
}