76

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
  • 5,262
  • 5
  • 23
  • 45
  • 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
  • possible duplicate of [PHP rename array keys in multidimensional array](http://stackoverflow.com/questions/2212948/php-rename-array-keys-in-multidimensional-array) – Caleb Mar 08 '12 at 04:23
  • 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

164

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,119
  • 5
  • 24
  • 39
alex
  • 460,746
  • 196
  • 858
  • 974
  • 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
  • 3
    very quick note: you save trees when using PHP 7 – pmiguelpinto Feb 10 '20 at 17:27
  • 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
39

Loop through, set new key, unset old key.

foreach($tags as &$val){
    $val['value'] = $val['url'];
    unset($val['url']);
}
gen_Eric
  • 214,658
  • 40
  • 293
  • 332
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,619
  • 22
  • 31
6

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
  • 61
  • 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
  • 3,974
  • 3
  • 21
  • 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
  • Thanks @griever, you save my time – Faridul Khan Aug 27 '20 at 11:58
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
  • 10,522
  • 7
  • 55
  • 63
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,093
  • 5
  • 20
  • 31
John
  • 11,516
  • 11
  • 87
  • 151
1

You can do it without any loop

Like below

$tags = str_replace("url", "value", json_encode($tags));  
$tags = json_decode($tags, true);
                    
Bhargav Variya
  • 587
  • 1
  • 8
  • 16
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
  • 51
  • 1
  • 4
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
  • 735
  • 4
  • 14
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
  • 21
  • 1
  • 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
  • 33
  • 1
  • 5
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;
ashish
  • 63
  • 1
  • 6