开发者

How to use a string as an array index path to retrieve a value?

Let 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 indexes 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 won't work
}


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


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 get_value(array_slice($indexes, 1), $arrayToAccess[$indexes[0]]);
   else
    return $arrayToAccess[$indexes[0]];
}


This is an old question but it has been referenced as this question comes up frequently.

There are recursive functions but I use a reference:

function array_nested_value($array, $path) {
    $temp = &$array;

    foreach($path as $key) {
        $temp =& $temp[$key];
    }
    return $temp;
}

$path  = array(0, 'Data', 'Name');
$value = array_nested_value($array, $path);


Try the following where $indexPath is formatted like a file path i.e.

'<array_key1>/<array_key2>/<array_key3>/...'.

function($indexPath, $arrayToAccess)
{
    $explodedPath = explode('/', $indexPath);
    $value =& $arrayToAccess;
    foreach ($explodedPath as $key) {
        $value =& $value[$key];
    }
    return $value;
}

e.g. using the data from the question, $indexPath = '1/Data/name/first' would return $value = Jane.


function($indexPath, $arrayToAccess)
{
    eval('$return=$arrayToAccess'.$indexPath.';');
    return $return;
}


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.


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));


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.


In addition to AbraCadaver:

function array_nested_value($array, $path) {

    foreach($path as $key) {

        $array = $array[$key];
    }

    return $array;
}

$path  = array(0, 'Data', 'Name');
$value = array_nested_value($array, $path);

Possible use

function get_array_value($array=array(), $path=array()){

    foreach($path as $key) {

        if(isset($array[$key])){

            $array=$array[$key];
        }
        else{

            $array=NULL;
            break;
        }
    }

    return $array;
}

function custom_isset($array=array(), $path=array()){

    $isset=true;

    if(is_array($array)&&is_null(get_array_value($array, $path))){

        $isset=false;
    }

    return $isset;
}

function is($array=array(), $path=array()){

    $is=false;

    if(is_array($array)){

        $array_value=get_array_value($array, $path);

        if(is_bool($array_value)){

            $is=$array_value;
        }
    }

    return $is;
}

Example

    $status=[];

    $status['updated']=true;

        if(is($status,array('updated'))){

                //do something...

        }

Resources

https://gist.github.com/rafasashi/0d3ebadf08b8c2976a9d


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']
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜