简体   繁体   中英

Get object with the highest property value in PHP array

I have an array with some objects like this:

$user_list = [$user1, $user2, $user3];

where

$user1 = new User()
$user1->number = 3
$user1->name = 'Mike'

$user2 = new User()
$user2->number = 8
$user2->name = 'Alex'

$user3 = new User()
$user3->number = 5
$user3->name = 'John'

I would like to retrieve the object from array with the highest number value with something like:

// return $user2
$userWithMaxNumber = some_function($user_list)  

You could linear-search through your list of users to find the one with the max number (read code comments for explanation):

function get_highest($arr) {
    $max = $arr[0]; // set the highest object to the first one in the array
    foreach($arr as $obj) { // loop through every object in the array
        $num = $obj->number; // get the number from the current object
        if($num > $max->number) { // If the number of the current object is greater than the maxs number:
            $max = $obj; // set the max to the current object
        }
    }
    return $max; // Loop is complete, so we have found our max and can return the max object
}

print_r(get_highest($user_list));

Or, for something which yields better time complexity you may consider storing your list of users in a max-heap

Simple:

//setup
class user{
    public $number;
}
//init
$user1 = new user();
$user1->number = 3;

$user2 = new user();
$user2->number = 8;

$user3 = new user();
$user3->number = 5;

$a = [$user1, $user2, $user3];
$max = 0;

//execute 
$o = array_reduce($a,function($c,$v){return$c->number<$v->number?$v:$c;},new user);

//output
print_r($o);

Output:

user Object
(
    [number:protected] => 8
)

Sandbox

Note only this part is the actual function:

$o = array_reduce($a,function($c,$v){return$c->number<$v->number?$v:$c;},new user);

The rest is just setup, but I think it is better to post the full working example and then explain off of that.

Here is the code uncompressed:

$o = array_reduce(
    $a,
    function($c,$v){
        return $c->number < $v->number ? $v : $c;
    },
    new user  //init a new user object for $c's initial value,  number = null
);

It's pretty strait forward, we do array reduce. If $v has a value greater then the carried item $c , we set the carried item to $v . If not we just return the carried item. And in the end, we are left with one item that has the max value.

If you wanted a bit more assurance and robustness, you can type hint the arguments of the callback to only accept user type objects:

$o = array_reduce(
    $a,
    function(user $c, user $v){
        return $c->number < $v->number ? $v : $c;
    },
    new user  //init a new user object for $c's initial value,  number = null
);

This binds us to the user classes API or interface. Which insures that only user objects are accepted, so we can reduce our error checks as we know what type of object it is, and what methods it has...

But, pretty much no matter what you do you have to iterate over the entire array at least one time to "discover" all the values.

Another option could be to add the users to an array and usort the array by ->number . Then get the first item from the array:

$users = [$user1, $user2, $user3];

usort($users, function($a, $b){
    return $a->number < $b->number;
});

var_dump($users[0]);
print_r($users[0]->number); // 8

Php demo

Note that usort mutates the $users array, so the original order changes (Except when it is already in the right order at the beginning)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM