XTRUST.ORG
XTRUST.ORG

Reputation: 3392

php | Search in array

I have an array and would like to find the object with maximal rating? My array looks like below:

Array
(
    [0] => stdClass Object
        (
            [created_by] => 905
            [rating] => 1
        )
    [1] => stdClass Object
        (
            [created_by] => 906
            [rating] => 2
        )
)

Thanks!

I have tried something like that:

static function maxValueInArray($array, $keyToSearch) {
        $currentMax = NULL;
        foreach($array as $arr) {
            foreach($arr as $key => $value) {
                if ($key == $keyToSearch && ($value >= $currentMax)) {
                    $currentMax = $value;
                }
            }
        }

        return $currentMax;
    }

Upvotes: 1

Views: 91

Answers (4)

kaiser
kaiser

Reputation: 22333

That's a pretty perfect example on when to use as Heap. You want to extend the default SPL \SplMaxHeap to know where to look for a comparison value - in your case that's the rating property.

Custom Max Heap

The benefit of using a heap is that PHP doesn't need to make an internal copy (as with normal arrays), which reduces memory usage quite a bit. It also is more readable and can be adjusted much easier.

class MaxRatingHeap extends \SplMaxHeap
{
    public function compare( $old, $new )
    {
        return $old->rating - $new->rating;
    }
}

Test

Some dummy data:

$objA = new \stdClass;
$objA->created_by = 103;
$objA->rating = 3;
$objB = new \stdClass;
$objB->created_by = 102;
$objB->rating = 2;
$objC = new \stdClass;
$objC->created_by = 100;
$objC->rating = 5;
$objD = new \stdClass;
$objD->created_by = 101;
$objD->rating = 1;

Run the test:

$it = new \MaxRatingHeap;
$it->insert( $objA );
$it->insert( $objB );
$it->insert( $objC );
$it->insert( $objD );

$it->rewind();
if ( ! $it->isEmpty() )
{
    printf( 'Our top rating is %s', $it->top()->rating );
    // Uncomment for proof that it is ordered by the `rating` property
    /*while ( $it->valid() )
    {
        var_dump( $it->current() );
        $it->next();
    }*/
}

Output:

Our top rating is 5

Upvotes: 0

Steve
Steve

Reputation: 20469

Should you need to access other objects in the array based on their rating (eg to show highest to lowest), you can sort the array:

usort($array, function($a, $b){
    if ($a->rating == $b->rating) {
        return 0;
    }
    return ($a->rating > $b->rating) ? -1 : 1;
});

To get the highest rated, select the 1st element:

$highest_rated = reset($array);
echo 'highest rating: ' . $highest_rated->rating;

If you only need to select the highest rated element, simply iterating the array once as per David's answer, will be more efficient

Upvotes: 0

akmozo
akmozo

Reputation: 9839

Try this :

<?php 

    ...

    $rating = -1;
    $max_object = (object) null;
    foreach ($your_array as $obj) {

        if($obj->rating > $rating){
            $rating = $value->rating;
            $max_object = $obj;
        }

    }

    print_r($max_object); // gives : stdClass Object ( [created_by] => 906 [rating] => 2 )

    ...

?>

Upvotes: 0

David162795
David162795

Reputation: 1866

Since your array is not sorted (I assume), you will need to read all values.

$maxobject = null;
foreach($array as $row)
  if(is_null($maxobject) || $maxobject->rating<$row->rating)
    $maxobject=$row;

Upvotes: 2

Related Questions