replace array keys with given respective keys
Asked Answered
A

11

22

I have an array like below

$old = array(
       'a' => 'blah',
       'b' => 'key',
       'c' => 'amazing',
       'd' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              )
       );

I have another array having keys to replace with key information.

$keyReplaceInfoz = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD');

I need to replace all keys of array $old with respective values in array $keyReplaceInfo.

Output should be like this

$old = array(
       'newA' => 'blah',
       'newB' => 'key',
       'newC' => 'amazing',
       'newD' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              )
       );

I had to do it manually as below. I am expecting better option. can anyone suggest better way to accomplish this?

$new = array();
foreach ($old as $key => $value)
{
     $new[$keyReplaceInfoz[$key]] = $value;
}

I know this can be more simpler.

Arrow answered 30/7, 2012 at 13:53 Comment(0)
W
30
array_combine(array_merge($old, $keyReplaceInfoz), $old)

I think this looks easier than what you posed.

Wisteria answered 30/7, 2012 at 14:8 Comment(6)
array_combine will only work if the keys and values are in the correct order, and there is a replacement for every key. (I looked at this as a solution myself).Womble
Actually the only problem with the above is that it won't work if there isn't a replacement for every key. Ordering is not an issue because of array_merge($old, $keyReplaceInfoz).Wisteria
There's a couple of problems, both related to the numer of elements. If the replacement array contains a key that is not in the old array, there will be a PHP warning (and nothing will be replaced). If the replacement array is missing a key from the old array, the key in the old array will be replaced with it's own valueWomble
You are right. The line makes certain assumptions about the structure of $keyReplaceInfoz, the questioner should specify whether all of the keys would be available or not.Wisteria
ahh sorry, I am reading these comments after these much years, thanks @Wisteria for awesome help at that time, And yes for my question and case, I had new keys available for each and every pair of old keys.Arrow
Actually you just need array_combine($keyReplaceInfoz, $old) or you'll be creating a different size arrayMultifoil
U
6
array_combine(
    ['newKey1', 'newKey2', 'newKey3'],
    array_values(['oldKey1' => 1, 'oldKey2' => 2, 'oldKey3' => 3])
);

This should do the trick as long as you have the same number of values and the same order.

Urethritis answered 25/7, 2018 at 15:58 Comment(2)
array_values() doesn't matter because array_combine() ignores the keys of both of its parameters.Deceleron
This is an inappropriate answer considering this is a mapping task. These two arrays do not attempt to associate old-new keys in a meaningful way -- they are merely slapped together based on position.Deceleron
F
4

IMO using array_combine, array_merge, even array_intersect_key is overkill. The original code is good enough, and very fast.

Forby answered 11/3, 2020 at 10:25 Comment(0)
D
2

Adapting @shawn-k solution, here is more cleaner code using array_walk, it will only replace desired keys, of course you can modify as per your convenience

array_walk($old, function($value,$key)use ($keyReplaceInfoz,&$old){
        $newkey = array_key_exists($key,$keyReplaceInfoz)?$keyReplaceInfoz[$key]:false;
        if($newkey!==false){$old[$newkey] = $value;unset($old[$key]);
        }
    });

    print_r($old);
Draw answered 17/3, 2016 at 5:41 Comment(0)
T
1

I just solved this same problem in my own application, but for my application $keyReplaceInfoz acts like the whitelist- if a key is not found, that whole element is removed from the resulting array, while the matching whitelisted keys get translated to the new values.

I suppose you could apply this same algorithm maybe with less total code by clever usage of array_map (http://php.net/manual/en/function.array-map.php), which perhaps another generous reader will do.

function filterOldToAllowedNew($key_to_test){       
    return isset($keyReplaceInfoz[$key_to_test])?$keyReplaceInfoz[$key_to_test]:false;
}   

$newArray = array();

foreach($old as $key => $value){
    $newkey = filterOldToAllowedNew($key);
    if($newkey){
       $newArray[$newkey] = $value;
    }
}

print_r($newArray);
Tm answered 24/4, 2015 at 7:0 Comment(0)
V
1

This question is old but since it comes up first on Google I thought I'd add solution.

// Subject
$old = array('foo' => 1, 'baz' => 2, 'bar' => 3));

// Translations    
$tr  = array('foo'=>'FOO', 'bar'=>'BAR');

// Get result
$new = array_combine(preg_replace(array_map(function($s){return "/^$s$/";}, 
           array_keys($tr)),$tr, array_keys($old)), $old);

// Output
print_r($new);

Result:

    
    Array
    (
       [FOO] => 1
       [baz] => 2
       [BAR] => 3
    )
Vociferous answered 13/10, 2018 at 22:59 Comment(1)
This answer is missing its educational explanation.Deceleron
G
0

This the solution i have implemented for the same subject:

/**
 * Replace keys of given array by values of $keys
 * $keys format is [$oldKey=>$newKey]
 *
 * With $filter==true, will remove elements with key not in $keys
 *
 * @param  array   $array
 * @param  array   $keys
 * @param  boolean $filter
 *
 * @return $array
 */
function array_replace_keys(array $array,array $keys,$filter=false)
{
    $newArray=[];
    foreach($array as $key=>$value)
    {
        if(isset($keys[$key]))
        {
            $newArray[$keys[$key]]=$value;
        }
        elseif(!$filter)
        {
            $newArray[$key]=$value;
        }
    }

    return $newArray;
}
Girdle answered 1/7, 2017 at 20:45 Comment(3)
How is this different than the method shown in question itself?Arrow
Because this method don't need have one replacement key for every key in the source array. The method shown in the question will give one error if any key of source array don't exists on replacement keys arrayStatist
You are right Juan, but I was sure that I will have all keys available for replacement. the question was to improve the method. your method still does the same looping!Arrow
D
0

This works irrespective of array order & array count. Output order & value will be based on replaceKey.

$replaceKey = array('a' => 'newA', 'b' => 'newB', 'c' => 'newC', 'd' => 'newD', 'e' => 'newE','f'=>'newF');

$array = array(
       'a' => 'blah',
       'd' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              ),
       'noKey'=>'RESIDUAL',
       'c' => 'amazing',
       'b' => 'key',
       );

$filterKey = array_intersect_key($replaceKey,$array);
$filterarray = array_intersect_key(array_merge($filterKey,$array),$filterKey);

$replaced = array_combine($filterKey,$filterarray);

//output
var_export($replaced);
//array ( 'newA' => 'blah', 'newB' => 'key', 'newC' => 'amazing', 'newD' => array ( 0 => 'want to replace', 1 => 'yes I want to' ) )
Demp answered 13/6, 2019 at 5:22 Comment(0)
H
0

If you're looking for a recursive solution to use on a multidimensional array, have a look at the below method. It will replace all keys requested, and leave all other keys alone.

/**
 * Given an array and a set of `old => new` keys,
 * will recursively replace all array keys that
 * are old with their corresponding new value.
 *
 * @param mixed $array
 * @param array $old_to_new_keys
 *
 * @return array
 */
function array_replace_keys($array, array $old_to_new_keys)
{
    if(!is_array($array)){
        return $array;
    }

    $temp_array = [];
    $ak = array_keys($old_to_new_keys);
    $av = array_values($old_to_new_keys);

    foreach($array as $key => $value){
        if(array_search($key, $ak, true) !== false){
            $key = $av[array_search($key, $ak)];
        }

        if(is_array($value)){
            $value = array_replace_keys($value, $old_to_new_keys);
        }

        $temp_array[$key] = $value;
    }

    return $temp_array;
}

Using OP's example array:

$old = array(
       'a' => 'blah',
       'b' => 'key',
       'c' => 'amazing',
       'd' => array(
                0 => 'want to replace',
                1 => 'yes I want to'
              )
       );
$replace = ["a" => "AA", 1 => 11];

var_export(array_replace_keys($old, $replace));

Gives the following output:

array (
  'AA' => 'blah',
  'b' => 'key',
  'c' => 'amazing',
  'd' => 
  array (
    0 => 'want to replace',
    11 => 'yes I want to',
  ),
)

DEMO

Inspired by the following snippet.

Hotpress answered 4/3, 2021 at 6:36 Comment(0)
L
0

This uses @Summoner's example but keeps @Leigh's hint in mind:

$start = microtime();
$array = [ "a" => 1, "b" => 2, "c" => 3 ];

function array_replace_key($array, $oldKey, $newKey) {
    $keys = array_keys($array);
    $idx = array_search($oldKey, $keys);
    array_splice($keys, $idx, 1, $newKey);
    return array_combine($keys, array_values($array));
}

print_r(array_replace_key($array, "b", "z"));
Lapillus answered 23/3, 2021 at 15:32 Comment(0)
B
-1
    <?php
$new = array(); 

foreach ($old as $key => $value)
{
     $new[$keyReplaceInfoz][$key] = $value;

}
?>
Benedicite answered 30/7, 2012 at 14:7 Comment(1)
This does not produce the output array the OP is asking for. Please check your code before posting.Womble

© 2022 - 2024 — McMap. All rights reserved.