5

I have a result set as an array from a database that looks like:

array (
    0 => array (
        "a" => "something"
        "b" => "something"
        "c" => "something"
    )
    1 => array (
        "a" => "something"
        "b" => "something"
        "c" => "something"
    )
    2 => array (
        "a" => "something"
        "b" => "something"
        "c" => "something"
    )
)

How would I apply a function to replace the values of an array only on the array key with b? Normally I would just rebuild a new array with a foreach loop and apply the function if the array key is b, but I'm not sure if it's the best way. I've tried taking a look at many array functions and it seemed like array_walk_recursive is something I might use, but I didn't have luck in getting it to do what I want. If I'm not describing it well enough, basically I want to be able to do as the code below does:

$arr = array();
foreach ($result as $key => $value)
{
    foreach ($value as $key2 => $value2)
    {
        $arr[$key][$key2] = ($key2 == 'b' ? $this->_my_method($value2) : $value2);
    }    
}

Should I stick with that, or is there a better way?

3 Answers 3

5

Using array_walk_recursive:

If you have PHP >= 5.3.0 (for anonymous functions):

array_walk_recursive($result, function (&$item, $key) {
    if ($key == 'b') {
        $item = 'the key is b!';
    }
});

Otherwise something like:

function _my_method(&$item, $key) {
    if ($key == 'b') {
        $item = 'the key is b!';
    }
}
array_walk_recursive($result, '_my_method');
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I had already tried array_walk_recursive as I said above, but it didn't work. Apparently I forgot to place the ampersand before the $item param! Working now.
Yup, easy mistake to make. Quoting the manual: If funcname needs to be working with the actual values of the array, specify the first parameter of funcname as a reference. Then, any changes made to those elements will be made in the original array itself.
0

Untested but I think this will work.

function replace_b (&$arr)
{
    foreach ($arr as $k => $v)
    {
        if ($k == 'b')
        {
            /* Do something */
        }
        if (is_array($v)
        {
            replace_b($arr[$k]);
        }
    }
}

The function will move through an array checking the keys for b. If the key points to an array it recursively follows it down.

2 Comments

@Jacob: I'm unfamiliar with the exact syntax of array_walk_recursive and didn't bother looking it up. Typing this was faster.
I wonder it is the performance difference between using array_walk_recursive vs. loop + calling the same function. Just like @JacobRelkin, I am used to doing it the loop + calling the same function, and it has worked just fine in the past.
0

use array_walk_recursive documented here

$replacer = function($x) {return "I used to be called $x";}; //put what you need here
$replaceB = function(&$v, $k) use ($replacer) {if ($k === 'b') $v = $replacer($v);};

array_walk_recursive($arr, $replaceB);

The replacer function might be overkill. You can replace it with a literal or anything you like.

1 Comment

I am not sure why someone decided to downvote your answer - it did work for me. I would however recommend cleaning it up, ie mentioning that the key is to pass $v as reference and changing the code to print the start and end values, and of course make it easier to read (not using unnecessary lambda functions or additional logic like $k == 'b' ).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.