How to rename sub-array keys in PHP?

When I var_dump on a variable called $tags (a multidimensional array) I get this:

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
)
)

I would like to rename all array keys called "url" to be called "value". What would be a good way to do this?

179926 次浏览

Loop through, set new key, unset old key.

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

You could use array_map() to do it.

$tags = array_map(function($tag) {
return array(
'name' => $tag['name'],
'value' => $tag['url']
);
}, $tags);
foreach ($basearr as &$row)
{
$row['value'] = $row['url'];
unset( $row['url'] );
}


unset($row);

This should work in most versions of PHP 4+. Array map using anonymous functions is not supported below 5.3.

Also the foreach examples will throw a warning when using strict PHP error handling.

Here is a small multi-dimensional key renaming function. It can also be used to process arrays to have the correct keys for integrity throughout your app. It will not throw any errors when a key does not exist.

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;
}

Usage is simple. You can either change a single key like in your example:

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

or a more complex multikey

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

It uses similar syntax as preg_replace() where the amount of $old_keys and $new_keys should be the same. However when they are not a blank key is added. This means you can use it to add a sort if schema to your array.

Use this all the time, hope it helps!

Talking about functional PHP, I have this more generic answer:

    array_map(function($arr){
$ret = $arr;
$ret['value'] = $ret['url'];
unset($ret['url']);
return $ret;
}, $tag);
}

Recursive php rename keys function:

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;
}
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);
}
}

Use:

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

It is from duplicated question

$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

Very simple approach to replace keys in a multidimensional array, and maybe even a bit dangerous, but should work fine if you have some kind of control over the source array:

$array = [ 'oldkey' => [ 'oldkey' => 'wow'] ];
$new_array = json_decode(str_replace('"oldkey":', '"newkey":', json_encode($array)));
print_r($new_array); // [ 'newkey' => [ 'newkey' => 'wow'] ]

This is how I rename keys, especially with data that has been uploaded in a spreadsheet:

function changeKeys($array, $new_keys) {
$newArray = [];


foreach($array as $row) {
$oldKeys = array_keys($row);
$indexedRow = [];


foreach($new_keys as $index => $newKey)
$indexedRow[$newKey] = isset($oldKeys[$index]) ? $row[$oldKeys[$index]] : '';


$newArray[] = $indexedRow;
}


return $newArray;
}

Based on the great solution provided by Alex, I created a little more flexible solution based on a scenario I was dealing with. So now you can use the same function for multiple arrays with different numbers of nested key pairs, you just need to pass in an array of key names to use as replacements.

$data_arr = [
0 => ['46894', 'SS'],
1 => ['46855', 'AZ'],
];


function renameKeys(&$data_arr, $columnNames) {
// change key names to be easier to work with.
$data_arr = array_map(function($tag) use( $columnNames) {
$tempArray = [];
$foreachindex = 0;
foreach ($tag as $key => $item) {
$tempArray[$columnNames[$foreachindex]] = $item;
$foreachindex++;
}
return $tempArray;
}, $data_arr);


}


renameKeys($data_arr, ["STRATEGY_ID","DATA_SOURCE"]);

this work perfectly for me

 $some_options = array();;
if( !empty( $some_options ) ) {
foreach( $some_options as $theme_options_key => $theme_options_value ) {
if (strpos( $theme_options_key,'abc') !== false) { //first we check if the value contain
$theme_options_new_key = str_replace( 'abc', 'xyz', $theme_options_key ); //if yes, we simply replace
unset( $some_options[$theme_options_key] );
$some_options[$theme_options_new_key] = $theme_options_value;
}
}
}
return  $some_options;

This doesn't have to be difficult in the least. You can simply assign the arrays around regardless of how deep they are in a multi-dimensional array:

$array['key_old'] = $array['key_new'];
unset($array['key_old']);

You can do it without any loop

Like below

$tags = str_replace("url", "value", json_encode($tags));
$tags = json_decode($tags, true);