0

Is there an elegant way of getting values from a massive multi-dimensional array using another array for the keys to lookup?

e.g.

$cats[A][A1][A11][A111] = $val;
$cats[A][A1][A11][A112] = $val;
$cats[A][A1][A12] = $val;
$cats[A][A1][A12][A121] = $val;
$cats[A][A2] = $val;
$cats[A][A2][A21] = $val;
$cats[A][A2][A22] = $val;
$cats[A][A2][A22][A221] = $val;
$cats[A][A2][A22][A222] = $val;

access values from $cats using $keys = Array ('A', 'A2', 'A22', 'A221');

without checking the length of $keys and doing something like...

switch (count($keys)) {
   case 1: $val = $cats[$keys[0]]; break;
   case 2: $val = $cats[$key[0]][$key[1]]; break;
   case 3: $val = $cats[$key[0]][$key[1]][$key[2]]; break;
   ...
}

many thanks.

3 Answers 3

0

Why not use recursion? Something like this:

function get_val($array, $keys) {
    if(empty($keys) || !is_array($keys) || !is_array($array)) return $array;
    else {
        $first_key = array_shift($keys);
        return get_val($array[$first_key], $keys);
    }
}

I originally had this written in a loop, but changed it to recursive for some reason. It's true, as yeoman said, that a recursive function is more likely than a loop to cause a stack overflow, especially if your array is sufficiently large (PHP does support end recursion), so here's a loop that should accomplish the same purpose:

// given a multidimensional array $array and single-dimensional array of keys $keys
$desired_value = $array;
while(count($keys) > 0) {
    $first_key = array_shift($keys);
    $desired_value = $desired_value[$first_key];
}
Sign up to request clarification or add additional context in comments.

4 Comments

if the array element $cats[A][A2][A22][A221] didn't exists, i'd like to add it. would the loop above return null in that case?
It would return null, yes. But it would also print a warning. You would need to check that $desired_value[$first_key] exists before accessing it. If it doesn't exist you can set $desired_value to null explicitly and break the loop. Then after the loop you can add the new key to the array.
Sorry, it's a PHP Notice, not a warning. You likely won't see it, depending on your PHP configuration, but best practice dictates you'd want to perform the check anyway.
now i'm having trouble writing a setting function! to set the value of say $cats[A][A2][A22][A221] using the same two arrays
0

That's fine so far. Otherwise you would need to iterate through array and check deepness. To make it dynamic I am sure you add keys into $keys array when constructing $cats. Using recursion also solution it will take more steps, more memory.

Comments

0

jburbage's suggestion of using recursion is OK in principle, but from what I know, PHP doesn't support end-recursion.

And the question was about a "massive" multidimensional array.

As "massive" suggests great depth in addition to great overall size, it's possible to run into a stack overflow with this solution, as it's usually possible to create data structures on the heap that reach deeper than the stack can cope with via recursion.

The approach is also not desirable from the performance point of view in this case.

Simply refactor jburbage's recursive solution to work in a loop, and you're almost there :-)

Here's jburbage's original suggested code once again:

function get_val($array, $keys) {
    if(empty($keys) || !is_array($keys) || !is_array($array)) return $array;
    else {
        $first_key = array_shift($keys);
        return get_val($array[$first_key], $keys);
    }
}

3 Comments

massive... well its only cats will be up to 6 deep
Ok, for 6 levels it really won't make any difference :-)
Btw, @jburbage: wow, I didn't know that PHP has end-recursion now - looks like the language is really growing up :-)

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.