1

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

3 Answers 3

5

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

Sign up to request clarification or add additional context in comments.

Comments

2

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.

1 Comment

I don't know why my answer was edited when I specifically asked in the comments How do you get the value of number for example $user1->number or $user1->getNumber()? in which the OP replied With a getter getNumber(). So to change it from that to a property seems, counter productive.
1

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)

5 Comments

maybe add a note that this mutates the original $users
The problem I have with this is that it sorts all of the data which is a big overhead considering you just want the one record.
@NigelRen I agree, is it another option to accomplish the required result.
@MarkAmery Why did you edit the question and answers?
@Thefourthbird The question previously didn't indicate how values set by setNumber could be retrieved, which led to a discussion in the comments (indicating the existence of a getNumber() method) without which the question wasn't answerable. I decided to eliminate the need for such explanation by swapping the question from using getter and setter methods to just directly setting a property, then flagged the comments for deletion.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.