Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using cakePHP's Hash class to extract data from an array

Tags:

cakephp-2.0

I have an array like this:

Array(
    [Rating] => Array(
        [0] => Array(
            [id] => 4
            [rating] => -1
        ),
        [1] => Array(
            [id] => 14
            [rating] => 9.7
        ),
        [2] => Array(
            [id] => 26
            [rating] => 9.55
        )
    )
)

I need to extract all the ratings >= 0 from this array, and JUST the numbers. I was doing this fine with Set::extract('/Rating/rating[rating>-1]', $video)

But I then learned that this is deprecated and you are supposed to use the Hash class now. So I looked up the new syntax and wrote:

Hash::extract($video, 'Rating.{n}.rating[rating>-1]');

which gives me the correct result, but it gives an annoying warning: Warning (4096): Argument 1 passed to Hash::_matches() must be an array, string given, called in E:\www\lib\Cake\Utility\Hash.php on line 131 and defined [CORE\Cake\Utility\Hash.php, line 170]

The warning doesn't occur when I don't have the condition in there (the [rating>-1]) but of course includes the -1's, which I don't want. What am I doing wrong here? Am I misusing this function somehow? Should I just use the deprecated Set class? Or should I just ignore the warning because it won't show up once I put this app into production mode?

like image 984
mittmemo Avatar asked Oct 09 '12 21:10

mittmemo


1 Answers

This question is old and I'm sure it's already resolved, but the CakePHP documentation is a bit unclear regarding usage of the Hash path syntax. So, in case someone else has come across this, here's what I found.

The syntax in the question is not correct. The correct syntax is 'Hash::extract($ratings, 'Rating.{n}[rating>-1].rating')'.

According to the documentation: "Tokens are composed of two groups. Expressions, are used to traverse the array data, while matchers are used to qualify elements.".

{n}[rating>-1] is considered one token. {n} is the expression which filters the array keys, in this case the key must be numeric. [rating>-1] is the matcher which filters the array elements, in this case the element must be an array that contains a key named rating and an associated value that is greater than -1. Once you have the array element then you can get the rating.

    $ratings = array(
        'Rating' => array(
            array(
                'id' => 4,
                'rating' => -1
            ),
            array(
                'id' => 14,
                'rating' => 9.7
            ),
            array(
                'id' => 26,
                'rating' => 9.55
            )
        )
    );
    print_r( Hash::extract($ratings, 'Rating.{n}[rating>-1].rating') );

Results in:

Array ( [0] => 9.7 [1] => 9.55 )
like image 139
Femi Avatar answered Sep 23 '22 17:09

Femi