2

I currently have an array in this format.

$test_arr = [
    'key1' => [
        'key2' => [
             'key3' => 'value',
         ],
    ],
    'key4' => 'value 2',
    'key5' => 'value 3',
];

My goal is to be able to replace 'value' in key3 with another value. The structure of the test_arr is not going to be known and will be completely different every single time, so I'm using a function to find the spot in the array where it is.

function array_find_deep($array, $search, $keys = array())
{
    foreach($array as $key => $value) {
        if (is_array($value)) {
            $sub = array_find_deep($value, $search, array_merge($keys, array($key)));
            if (count($sub)) {
                return $sub;
            }
        } elseif ($value === $search) {
            return array_merge($keys, array($key));
        }
    }

    return array();
}

When I use this function with my test array like so:

$key = array_find_deep($test_arr, 'value');

it returns an array with the contents:

['key1','key2','key3']

I now know the path in the array I need to go to, but I'm not sure how to take advantage of this to change the value of key3

I've made an attempt by creating another function

function replaceValueWithKeyMap($key, &$arr, $new_val, &$i = 0) {
    $length = count($key);
    if ($i >= $length-1) {
        $arr[$key[$i]] = $new_val;
        return $arr;
    } else {
        $i++;           
        replaceValueWithKeyMap($key, $arr[$key[$i]], $new_val, $i);
    }
}

but when I do

replaceValueWithKeyMap($key,$test_arr,'newvalue');

I just get back

$test_arr = [
    'key1' => [
        'key2' => [
             'key3' => 'value',
         ],
    ],
    'key4' => 'value 2',
    'key5' => 'value 3',
    'key3' => [
       'key3' => 'newvalue',
    ],
 ];

If I have an array of the path of keys how do I take advantage of that to change a value using that path.

1 Answer 1

1

In your function replaceValueWithKeyMap(), you can avoid a recursive call, by looping over the keys and hold a reference of the current "path" in the array.

function replaceValueWithKeyMap($keys, &$arr, $new_val) {
    if (empty($keys)) return ; // Don't change $arr if $keys is empty
    $ref =& $arr ; // path starts with the root of $arr
    foreach ($keys as $key) { // for each keys
        $ref =& $ref[$key] ; // update the path
    }
    $ref = $new_val; // apply the new value
}

Will outputs:

Array
(
    [key1] => Array
        (
            [key2] => Array
                (
                    [key3] => newvalue
                )

        )

    [key4] => value 2
    [key5] => value 3
)

The complete code (demo) :

function array_find_deep($array, $search, $keys = array())
{
    foreach($array as $key => $value) {
        if (is_array($value)) {
            $sub = array_find_deep($value, $search, array_merge($keys, array($key)));
            if (count($sub)) {
                return $sub;
            }
        } elseif ($value === $search) {
            return array_merge($keys, array($key));
        }
    }

    return array();
}
function replaceValueWithKeyMap($keys, &$arr, $new_val) {
    if (empty($keys)) return ; // Don't change $arr if $keys is empty
    $ref =& $arr ; // path starts with the root of $arr
    foreach ($keys as $key) { // for each keys
        $ref =& $ref[$key] ; // update the path
    }
    $ref = $new_val; // apply the new value
}
$test_arr = [
    'key1' => [
        'key2' => [
             'key3' => 'value',
         ],
    ],
    'key4' => 'value 2',
    'key5' => 'value 3',
];

$key = array_find_deep($test_arr, 'value');
replaceValueWithKeyMap($key,$test_arr,'newvalue');
print_r($test_arr);
Sign up to request clarification or add additional context in comments.

Comments

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.