Sign in to follow this  

Sorting a complex array

This topic is 3553 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

(I'm using PHP for this). I have an array named "player_array", and each block of the array contains an object player (for example):
class player
{
    var $name, $level;
}

$player_array = array();

$player_array[0] = new player();
$player_array[1] = new player();
$player_array[2] = new player();

$player_array[0]->name = "Tom";
$player_array[1]->name = "Bob";
$player_array[2]->name = "Joe";

$player_array[0]->level = 23;
$player_array[1]->level = 11;
$player_array[2]->level = 42;
I want to be able to sort the array by the player's name ($player_array[#]->name) and also by player's level ($player_array[#]->level). Is this possible? If so, can someone help me out? I'm REALLY lost.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
I don't use PHP, but a quick google gives me this as a potential candidate.

I took a look at that function (google'd it) and I thought it might do the job, but when I tried to even grasp how it is supposed to be used, it just confused me to death.

Share this post


Link to post
Share on other sites
As I said, I don't know PHP all that well, but I guess it would look something like this:

function player_name_sorter($one, $two)
{
if ($one->name == $two->name) {
return 0;
}
return ($one->name < $two->name) ? -1 : 1;
}


usort($player_array, "player_name_sorter");

// now they are sorted by name

function player_level_sorter($one, $two)
{
if ($one->level == $two->level) {
return 0;
}
return ($one->level < $two->level) ? -1 : 1;
}


usort($player_array, "player_level_sorter");

// now, sorted by level

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
As I said, I don't know PHP all that well, but I guess it would look something like this:
*** Source Snippet Removed ***


Wow, that worked perfectly! Thanks so much. :D

Share this post


Link to post
Share on other sites
Quote:
Original post by Exershio
Quote:
Original post by rip-off
As I said, I don't know PHP all that well, but I guess it would look something like this:
*** Source Snippet Removed ***


Wow, that worked perfectly! Thanks so much. :D


Danger, Will Robinson... In order for the above to work, usort must be stable.

Apparently, in PHP above version 4, the usort is no longer stable (seems to use quick sort). As such, calling it several times in sequence is not guaranteed to produce expected results.

Unfortunately, the solution doesn't appear to be trivial (unless you implement your own algorithm).

Or, you can try your luck with some voodoo.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Danger, Will Robinson... In order for the above to work, usort must be stable.


Hold on. The OP didn't say anything about sorting "by name, then by player"; just about being able to do both sorts "by name" and - at some later point - "by player".

But in the first case, you can still do it by just making a sort predicate that implements the "compare by name, then by player" logic:


function player_name_then_level_sorter($one, $two)
{
if $one->name < $two->name { return -1; }
if $one->name > $two->name { return 1; }
if $one->level < $two->level { return -1; }
if $one->level > $two->level { return 1; }
return 0;
}

usort($player_array, "player_name_then_level_sorter");


Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Quote:
Original post by Antheus
Danger, Will Robinson... In order for the above to work, usort must be stable.


Hold on. The OP didn't say anything about sorting "by name, then by player"; just about being able to do both sorts "by name" and - at some later point - "by player".


Hmm, I misinterpreted the description then:
Quote:
by the player's name ($player_array[#]->name) and also by player's level ($player_array[#]->level)


Name and also level. To me that read as at the same time, in which case repeated stable sorts are perfectly valid solution.

If they were two separate sorts, I'd use "name or level".

Share this post


Link to post
Share on other sites

This topic is 3553 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this