如何在PHP中重命名子数组键?

78
当我使用var_dump在一个名为$tags的变量上(一个多维数组),我得到这个结果:
Array
(
    [0] => Array
        (
            [name] => tabbing
            [url] => tabbing
        )
[1] => Array ( [name] => tabby ridiman [url] => tabby-ridiman )
[2] => Array ( [name] => tables [url] => tables )
[3] => Array ( [name] => tabloids [url] => tabloids )
[4] => Array ( [name] => taco bell [url] => taco-bell )
[5] => Array ( [name] => tacos [url] => tacos ) )
我想将所有名为"url"的数组键重命名为"value"。有什么好的方法可以做到这一点?

请参考此SO帖子:https://dev59.com/RXVC5IYBdhLWcg3wnCaA - Bjoern
在 PHP >= 5.5.0 中,有 array_column 函数,可能对此非常有用。 - kenorb
14个回答

168
你可以使用array_map()来完成它。
$tags = array_map(function($tag) {
    return array(
        'name' => $tag['name'],
        'value' => $tag['url']
    );
}, $tags);

10
好的!快速提示:闭包(匿名函数)只在PHP 5.3.0及以上版本中可用。 - Mallard
11
快速提醒:你需要使用PHP 5.6或更高版本,否则你将在运行不受支持的PHP版本,可能会遇到安全问题。 - John Hunt
你好,我有一个包含多列的案例,是否有一种类似的函数可以不覆盖每个项目,而只是修改它们?否则需要写很多代码... - Valter Ekholm
警告:这将删除您未重命名的所有键。 - hanshenrik

41

遍历数组,设置新的键名,删除旧的键名。

foreach($tags as &$val){
    $val['value'] = $val['url'];
    unset($val['url']);
}

8
谈到PHP的功能性,我有一个更通用的答案:
    array_map(function($arr){
        $ret = $arr;
        $ret['value'] = $ret['url'];
        unset($ret['url']);
        return $ret;
    }, $tag);
}

8

递归的PHP重命名键函数:

function replaceKeys($oldKey, $newKey, array $input){
    $return = array(); 
    foreach ($input as $key => $value) {
        if ($key===$oldKey)
            $key = $newKey;

        if (is_array($value))
            $value = replaceKeys( $oldKey, $newKey, $value);

        $return[$key] = $value;
    }
    return $return; 
}

2
这是一个非常棒的解决方案!它可以在多维数组中重命名任何位置的键。谢谢,这节省了我数小时的工作时间。 - Clinton

6
foreach ($basearr as &$row)
{
    $row['value'] = $row['url'];
    unset( $row['url'] );
}

unset($row);

2
警告:即使在foreach循环之后,$row的引用和最后一个数组元素仍然存在。建议使用unset()销毁它。否则,您可能会遇到意外的行为。请参阅https://secure.php.net/manual/en/control-structures.foreach.php,https://dev59.com/anA75IYBdhLWcg3wboUz,https://dev59.com/9W445IYBdhLWcg3wO3xu。 - Pang
至少在迭代后你没有使用$row,并且foreach是在函数内执行的,它会在函数结束后自动销毁。有时,如果您中断了迭代并希望在foreach之外使用最后迭代的元素,则$row可能很有用。 - StefansArya

3

这个应该在大多数PHP 4+版本中都可用。使用匿名函数的数组映射在5.3以下版本不支持。

此外,当使用严格的PHP错误处理时,foreach示例会抛出警告。

这是一个小型的多维键重命名函数。它还可以用于处理数组,以使整个应用程序的键正确。当键不存在时,它不会抛出任何错误。

function multi_rename_key(&$array, $old_keys, $new_keys)
{
    if(!is_array($array)){
        ($array=="") ? $array=array() : false;
        return $array;
    }
    foreach($array as &$arr){
        if (is_array($old_keys))
        {
            foreach($new_keys as $k => $new_key)
            {
                (isset($old_keys[$k])) ? true : $old_keys[$k]=NULL;
                $arr[$new_key] = (isset($arr[$old_keys[$k]]) ? $arr[$old_keys[$k]] : null);
                unset($arr[$old_keys[$k]]);
            }
        }else{
            $arr[$new_keys] = (isset($arr[$old_keys]) ? $arr[$old_keys] : null);
            unset($arr[$old_keys]);
        }
    }
    return $array;
}

使用方法很简单。您可以像示例中那样更改单个密钥:

multi_rename_key($tags, "url", "value");

或者一个更复杂的多键

multi_rename_key($tags, array("url","name"), array("value","title"));

它使用与preg_replace()相似的语法,其中$old_keys和$new_keys的数量应该相同。但是,当它们不同时,会添加一个空键。这意味着您可以使用它向数组添加排序架构。
经常使用它,希望能帮到您!

或者你可以直接使用array_map($tags,create_function('$tag','return array( "name" => $tag["name"], "value" => $tag["url"]')); - Noishe
当您进行系统化重命名时,情况会变得混乱不堪。此外,create_function使用eval,如果可能的话,显然应该避免使用。 - Stephen Fraser
1
为什么要这么不必要地复杂化呢? - ahnbizcad

1
非常简单的方法来替换多维数组中的键,可能有点危险,但如果您对源数组有一定的控制,应该可以正常工作。
$array = [ 'oldkey' => [ 'oldkey' => 'wow'] ];
$new_array = json_decode(str_replace('"oldkey":', '"newkey":', json_encode($array)));
print_r($new_array); // [ 'newkey' => [ 'newkey' => 'wow'] ]

如果我想将这个数组中的所有键替换为"q",它能行得通吗?{"q0":"String1","q1":"string2","q2":"string3"} 我需要它变成这样:{"q":"String1","q":"string2","q":"string3"} 这是Google翻译API v2中多行翻译的要求...可能吗? - Varg
1
不,那是不可能的。在PHP数组中,同一层级的元素不能具有相同的键。此外,生成的字符串也不会是一个有效的JSON字符串。(因为JSON也不允许重复的键) - Jules Colle

1
这并不需要很困难。您只需简单地分配多维数组中任何深度的数组即可:
$array['key_old'] = $array['key_new'];
unset($array['key_old']);

必须是 $array['key_new'] = $array['key_old'];,当然了。这是 此答案 的副本。 - AmigoJack

0

这是一个重复的问题

$json = '[   
{"product_id":"63","product_batch":"BAtch1","product_quantity":"50","product_price":"200","discount":"0","net_price":"20000"},    
{"product_id":"67","product_batch":"Batch2","product_quantity":"50","product_price":"200","discount":"0","net_price":"20000"}
]';

$array = json_decode($json, true);

$out = array_map(function ($product) {
  return array_merge([
    'price'    => $product['product_price'],
    'quantity' => $product['product_quantity'],
  ], array_flip(array_filter(array_flip($product), function ($value) {
    return $value != 'product_price' && $value != 'product_quantity';
  })));
}, $array);

var_dump($out);

https://repl.it/@Piterden/Replace-keys-in-array


0
class DataHelper{

    private static function __renameArrayKeysRecursive($map = [], &$array = [], $level = 0, &$storage = []) {
        foreach ($map as $old => $new) {
            $old = preg_replace('/([\.]{1}+)$/', '', trim($old));
            if ($new) {
                if (!is_array($new)) {
                    $array[$new] = $array[$old];
                    $storage[$level][$old] = $new;
                    unset($array[$old]);
                } else {
                    if (isset($array[$old])) {
                        static::__renameArrayKeysRecursive($new, $array[$old], $level + 1, $storage);
                    } else if (isset($array[$storage[$level][$old]])) {
                        static::__renameArrayKeysRecursive($new, $array[$storage[$level][$old]], $level + 1, $storage);
                    }
                }
            }
        }
    }

    /**
     * Renames array keys. (add "." at the end of key in mapping array if you want rename multidimentional array key).
     * @param type $map
     * @param type $array
    */
    public static function renameArrayKeys($map = [], &$array = [])
    {
        $storage = [];
        static::__renameArrayKeysRecursive($map, $array, 0, $storage);
        unset($storage);
    }
}

使用:

DataHelper::renameArrayKeys([
    'a' => 'b',
    'abc.' => [
       'abcd' => 'dcba'
    ]
], $yourArray);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接