Jump to content

Changing array keys


NotionCommotion

Recommended Posts

I would fist ask why this needs to be done. The first array is being built somehow. It would be best to change the process of building that array to be in the required format rather than trying to reformat it later. 

 

You can create a new array with different keys using array_combine(), but it requires that the number of keys and values are the same. From your example, I would imagine the number of primary arrays (three in your example) could likely change. Although, I don't know that array_combine() would work on multi-dimensional arrays.

 

You will likely need to run a loop over the parent array and change the child keys. But, not knowing what your logic will be, not sure what the best method would be. E.g. is it always a/b changing to c/b? Would the keys be dynamic? Etc.

Edited by Psycho
Link to comment
Share on other sites

I would fist ask why this needs to be done. The first array is being built somehow. It would be best to change the process of building that array to be in the required format rather than trying to reformat it later. 

 

The PHP webserver retrieves the data from another server's API using cURL as [['id'=>123,'name'='hello]...], and needs to send it to the browser client as [['id'=>123,'label='hello]...] and will be used by jQueryUI's autocomplete plugin.  The key name "name" always needs to change to "label".

Link to comment
Share on other sites

The PHP webserver retrieves the data from another server's API using cURL as [['id'=>123,'name'='hello]...], and needs to send it to the browser client as [['id'=>123,'label='hello]...] and will be used by jQueryUI's autocomplete plugin.  The key name "name" always needs to change to "label".

 

That is VERY useful information. I appreciate that you were trying to simplify the question, by not including "real" data or how the information is generated and used. But, those details can greatly change the response. In this case, I would probably create a function and have it dynamically change 'name' to 'label' if it exists in the data - regardless of what position it is in. That way, if the API ever changes the order of the fields your code would not break.

  • Like 1
Link to comment
Share on other sites

You could get fancy and try to use something like array_walk/array_map etc, but ultimately that's the same as just looping over the array with foreach and renaming the key. I'd just do the foreach loop and call it a day, I don't think you can really do much better than that. Make a function out of it so you can re-use the logic elsewhere if need be.

 

Off the top of my head, something like this should work:

function rename_keys($input, $from, $to){
    $out = [];
    foreach ($input as $arr){
        if (isset($arr[$from])){
            $arr[$to] = $arr[$from];
            unset($arr[$from]);
        }

        $out[] = $arr;
    }

    return $out;
}
Fancier array_map way:

function rename_keys($from, $to){
    return function($arr) use ($from, $to){
        if (isset($arr[$from])){
            $arr[$to] = $arr[$from];
            unset($arr[$from]);
        }
        return $arr;
    };
}

$new = array_map(rename_keys('name', 'label'), $original);
Edited by kicken
  • Like 1
Link to comment
Share on other sites

Small modification suggestion to kicken's first code example. The code is 1/2 way there to modifying the current array data. Might as well go all the way - then no need to create an "$out" array to store the values. Just return the input array when done processing.

 

function rename_keys($input, $from, $to) {
    foreach ($input as $key => $arr){
        if (isset($arr[$from])){
            $input[$key][$to] = $arr[$from];
            unset($input[$key][$from]);
        }
    }
    return $input;
}
  • Like 1
Link to comment
Share on other sites

I would just pass it as reference, but that's just me.

function changeKeyName (&$arr, $from, $to) {
     foreach($arr as &$k=>$val) $k = $k == $from ? $k = $to : $k;
}

$arr1 = ['abc'=>'one','def'=>'two','abc'=>'three'];

changeKeyName($arr1, "abc", "xyz");

Note: This is untested.

Link to comment
Share on other sites

I would just pass it as reference, but that's just me.

function changeKeyName (&$arr, $from, $to) {
     foreach($arr as &$k=>$val) $k = $k == $from ? $k = $to : $k;
}

$arr1 = ['abc'=>'one','def'=>'two','abc'=>'three'];

changeKeyName($arr1, "abc", "xyz");

Note: This is untested.

Note sure if this will work with the nested arrays, but I am interested on how it works.  I've never done references within references.  Let me make sure I know what is going on.

 

Send $arr to changeKeyName as a reference, so I am really working on the array outside of the function.

Pass $k as a reference to the foreach loop, so I am really working on the $k outside of the foreach loop and therefore working on the key of $arr outside of the function?

 

And then, if $k==$from, set $k=$to within the ternary and set $k equal to the new $k outside of the ternary?

Link to comment
Share on other sites

Using a reference means you have two variables that point to the same underlying value. As such changes to that value by either variable are reflected by both variables.

 

In the case of passing $arr by reference as the function parameter this means any changes you make to $arr within the function will be reflected in the variable originally passed to the function.

 

That is the theory behind using a referenced for $k also, but PHP does not allow the key in a foreach to be by-reference so it doesn't actually work.

Link to comment
Share on other sites

The ternary just checks if $k == $from and if so changes it to $to otherwise leaves it as is. The assignment to $k within the ternary isn't actually necessary, you can just do this:

$k = $k==$from?$to:$k;
The ternary will return either $to or $k depending on the condition. Whatever it returns is then assigned to $k.
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.