78

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?

Top-Master
  • 7,611
  • 5
  • 39
  • 71
  • See this SO post: http://stackoverflow.com/questions/240660/in-php-how-do-you-change-the-key-of-an-array-element – Bjoern Mar 07 '12 at 16:19
  • In PHP >= 5.5.0 there is [`array_column`](http://php.net/array_column) which could be potentially useful for that. – kenorb Nov 30 '15 at 18:23

14 Answers14

167

You could use array_map() to do it.

$tags = array_map(function($tag) {
    return array(
        'name' => $tag['name'],
        'value' => $tag['url']
    );
}, $tags);
kamal pal
  • 4,187
  • 5
  • 25
  • 40
alex
  • 479,566
  • 201
  • 878
  • 984
  • 10
    nice! quick note: closures (anonymous functions) are only available in php 5.3.0+ – Mallard Jan 29 '14 at 09:57
  • 11
    quick note: You need to be using PHP 5.6 or greater, otherwise you're running an unsupported version of php and can possibly expect security issues. – John Hunt Sep 09 '16 at 10:10
  • Hello, I have a case with several columns, is there a way to use similar function that does not overwrite each item, but just alter? So much coding else... – Valter Ekholm Aug 09 '20 at 10:51
  • Warning: this will erase all keys that you did not rename. – hanshenrik May 21 '23 at 01:35
41

Loop through, set new key, unset old key.

foreach($tags as &$val){
    $val['value'] = $val['url'];
    unset($val['url']);
}
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
8

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);
}
Community
  • 1
  • 1
CharybdeBE
  • 1,791
  • 1
  • 20
  • 35
7

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; 
}
Bill Barsch
  • 71
  • 1
  • 4
  • 1
    This is a brilliant solution! it renames the key wherever it is in the multi-dimensional array. Thank you this saved me hours of work. – Clinton Jan 25 '19 at 10:12
6
foreach ($basearr as &$row)
{
    $row['value'] = $row['url'];
    unset( $row['url'] );
}

unset($row);
Mr Griever
  • 4,014
  • 3
  • 23
  • 41
  • 2
    **Warning**: Reference of $row and the last array element remain even after the foreach loop. It is recommended to destroy it by unset(). Otherwise you may experience unexpected behavior. See https://secure.php.net/manual/en/control-structures.foreach.php, https://stackoverflow.com/q/3307409, https://stackoverflow.com/q/4969243 – Pang Apr 10 '18 at 05:26
  • At least you don't use `$row` after the iteration and `foreach` is executed inside a function, it will automatically destroyed after the end of function. Sometime `$row` can be useful if you have break the iteration and want to use the last iterated element outside `foreach`. – StefansArya Nov 02 '18 at 14:09
3

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!

1

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'] ]
Jules Colle
  • 11,227
  • 8
  • 60
  • 67
  • can it work if I want to replace all the keys in this array to "q"? ```{"q0":"String1","q1":"string2","q2":"string3"}``` I need to have it like this: ```{"q":"String1","q":"string2","q":"string3"}``` it is the requirement for the multiline translation in google translation api v2... could it be possible? – Varg Aug 17 '23 at 14:38
  • no, That's impossible. Elements in a PHP array cannot have the same key at the same level. Also, the resulting string would not be a valid JSON string. (Because JSON also doesn't allow duplicate keys) – Jules Colle Aug 24 '23 at 23:40
1

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']);
MaartenDev
  • 5,631
  • 5
  • 21
  • 33
John
  • 1
  • 13
  • 98
  • 177
  • Must be `$array['key_new'] = $array['key_old'];`, of course. And it's a duplicate of [this answer](https://stackoverflow.com/a/9605202/4299358). – AmigoJack Jul 29 '22 at 22:10
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);
    }
}

Use:

DataHelper::renameArrayKeys([
    'a' => 'b',
    'abc.' => [
       'abcd' => 'dcba'
    ]
], $yourArray);
Alexander
  • 125
  • 1
  • 6
0

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

Piterden
  • 771
  • 5
  • 17
0

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;
}
Dankim
  • 81
  • 2
  • 4
0

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"]);
otay
  • 35
  • 1
  • 6
0

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;
Ahish
  • 73
  • 1
  • 7
0

You can do it without any loop

Like below

$tags = str_replace("url", "value", json_encode($tags));  
$tags = json_decode($tags, true);
                    
Bhargav Variya
  • 725
  • 1
  • 10
  • 18