tags:

views:

100

answers:

6

Say I have an array like:

Array
(
    [0] => Array
        (
            [Data] => Array
                (
                    [id] => 1
                    [title] => Manager
                    [name] => John Smith
                )
         )
    [1] => Array
        (
            [Data] => Array
                 (
                     [id] => 1
                     [title] => Clerk
                     [name] =>
                         (
                             [first] => Jane
                             [last] => Smith
                         )
                 )

        )

)

I want to be able to build a function that I can pass a string to that will act as the array index path and return the appropriate array value without using eval(). Is that possible?

function($indexPath, $arrayToAccess)
{
    //$indexPath would be something like [0]['Data']['name'] which would return 
    //"Manager" or it could be [1]['Data']['name']['first'] which would return 
    //"Jane" but the amount of array indexs that will be in the index path can 
    //change, so there might be 3 like the first example, or 4 like the second.

    return $arrayToAccess[$indexPath] <-obviously wont work
}
A: 

You have to parse indexPath string. Chose some separator (for example "."), read text until "." that would be the first key, then read rest until next, that would be next key. Do that until no more dots.

You ken store key in array. Do foreach loop on this array to get seeked element.

Maciek Sawicki
+1  A: 

If you already know the exact array element that you are pulling out why write a function to do it? What's wrong with just

$array[0]['data']['title']
RMcLeod
+1  A: 

you might use an array as path (from left to right), then a recursive function:

$indexes = {0, 'Data', 'name'};

function get_value($indexes, $arrayToAccess)
{
   if(count($indexes) > 1) 
    return getValue(array_slice($indexes, 1), $arrayToAccess[$indexes[0]]);
   else
    return $arrayToAccess[$indexes[0]];
}
najmeddine
Nice. Note to copy-and-pasters: recursive call to 'getValue' doesn't quite match function name 'get_value'. They should match to work properly.
grossvogel
A: 

Here is one way to get the job done, if string parsing is the way you want to go.

$data[0]["Data"]["stuff"] = "cake";

$path = "[0][\"Data\"]['stuff']";

function indexPath($path,$array){
    preg_match_all("/\[['\"]*([a-z0-9_-]+)['\"]*\]/i",$path,$matches);

    if(count($matches[1]) > 0) {
        foreach ($matches[1] as $key) {
                if (isset($array[$key])) {
                        $array = $array[$key];
                } else {
                        return false;
                }
        }
    } else {
        return false;
    }

return $array;
}

print_r(indexPath($path,$data));
SleighBoy
A: 

A preg_match_all, cycling through the matched results would give you CLOSE to the result you wanted. You need to be careful with all of the strategies listed here for lost information. For instance, you have to devise some way to ensure that 55 stays as type int and isn't parsed as type string.

Steven Xu
A: 

A Bit later, but... hope helps someone:

// $pathStr = "an:string:with:many:keys:as:path";
$paths = explode(":", $pathStr); 
$itens = $myArray;
foreach($paths as $ndx){
    $itens = $itens[$ndx];
}

Now itens is the part of the array you wanted to.

[]'s

Labs

Labs