14

I have a string like this:

$string = 'one/two/three/four';

which I turn it into a array:

$keys = explode('/', $string);

This array can have any number of elements, like 1, 2, 5 etc.

How can I assign a certain value to a multidimensional array, but use the $keys I created above to identify the position where to insert?

Like:

$arr['one']['two']['three']['four'] = 'value';

Sorry if the question is confusing, but I don't know how to explain it better

2

5 Answers 5

16

This is kind of non-trivial because you want to nest, but it should go something like:

function insert_using_keys($arr, $keys, $value){
    // we're modifying a copy of $arr, but here
    // we obtain a reference to it. we move the
    // reference in order to set the values.
    $a = &$arr;

    while( count($keys) > 0 ){
        // get next first key
        $k = array_shift($keys);

        // if $a isn't an array already, make it one
        if(!is_array($a)){
            $a = array();
        }

        // move the reference deeper
        $a = &$a[$k];
    }
    $a = $value;

    // return a copy of $arr with the value set
    return $arr;
}
Sign up to request clarification or add additional context in comments.

Comments

9
$string = 'one/two/three/four';
$keys = explode('/', $string);
$arr = array(); // some big array with lots of dimensions
$ref = &$arr;

while ($key = array_shift($keys)) {
    $ref = &$ref[$key];
}

$ref = 'value';

What this is doing:

  • Using a variable, $ref, to keep track of a reference to the current dimension of $arr.
  • Looping through $keys one at a time, referencing the $key element of the current reference.
  • Setting the value to the final reference.

6 Comments

I get a "connection closed by server" when I try this :)
What if $keys contains 0 or NULL?
He asked how to solve the problem, not write error-checking for it :)
It's possible to solve the problem even given those conditions, your code fails miserably in that situation.
And your solution "fails miserably" when $arr is not an array, along with a handful of other cases. Bullet-proof error-checking is not a prerequisite for a correct answer.
|
1

You'll need to first make sure the key's exist, then assign the value. Something like this should work (untested):

function addValueByNestedKey(&$array, $keys, $value) {
    $branch = &$array;
    $key = array_shift($keys);
    // add keys, maintaining reference to latest branch:
    while(count($keys)) {
        $key = array_pop($keys);
        if(!array_key_exists($key, $branch) {
            $branch[$key] = array();
        }
        $branch = &$branch[$key];
    }
    $branch[$key] = $value;
}

// usage:
$arr = array();
$keys = explode('/', 'one/two/three/four');

addValueByNestedKey($arr, $keys, 'value');

Comments

1

it's corny but:

function setValueByArrayKeys($array_keys, &$multi, $value) {
     $m = &$multi
     foreach ($array_keys as $k){
         $m = &$m[$k];
     }
     $m = $value;
}

5 Comments

This won't work. $multi = $multi[$k] creates a copy, it's not a reference, so you're not actually modifying anything when you do $multi = $value, except the final array.
it still won't work, you're creating copies, not references.
sorry bro, i'm a python guy and by default you get references in python, edited AGAIN
So believe it or not, this still doesn't do what you expect, taking $multi as a parameter generates a copy, the first reference you assign to $m is to the copy, not the original. You can (a) make $multi a reference in the parameter list or (b) return $multi.
In general, if you're not familiar with the target language, you ought to run your code.
0
    $arr['one']['two']['three']['four'] = 'value';

    $string = 'one/two/three/four';
    $ExpCheck = explode("/", $string);
    $CheckVal = $arr;
    foreach($ExpCheck AS $eVal){
        $CheckVal = $CheckVal[$eVal]??false;
        if (!$CheckVal)
            break;
    }
    if ($CheckVal) {
        $val =$CheckVal;
    }

this will give u your value in array.

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.