FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » sort array of objects by muliple values
Show: Today's Messages :: Polls :: Message Navigator
Return to the default flat view Create a new topic Submit Reply
Re: sort array of objects by muliple values [message #172047 is a reply to message #172029] Fri, 28 January 2011 11:06 Go to previous message
Helmut Chang is currently offline  Helmut Chang
Messages: 22
Registered: September 2010
Karma:
Junior Member
Am 27.01.2011 22:38, schrieb Max:
> On Jan 27, 10:27 pm, Denis McMahon<denis.m.f.mcma...@googlemail.com>
> wrote:
>>
>> <?php
>>
>> class User {
>> private $firstname;
>> private $surname;
>> private $birthday;
>>
>> function __construct($firstname, $surname, $birthday) {
>> $this->firstname = $firstname;
>> $this->surname = $surname;
>> $this->birthday = $birthday;
>> }
>> function __get($n) {
>> return $this->$n;
>> }
>>
>> }
>>
>> function cmp_User($a, $b)
>> {
>> if ($a->birthday == $b->birthday) {
>> if ($a->surname == $b->surname) {
>> return 0;
>> }
>> return ($a->surname< $b->surname) ? -1 : 1;
>> }
>> return ($a->birthday< $b->birthday) ? -1 : 1;
>>
>> }
>>
>> $a = array (
>> new User('Alice', 'Smith', '1960-01-01'),
>> new User('Michael', 'Jordan', '1950-01-01'),
>> new User('Kevin', 'Dilan', '1950-01-01'),
>> );
>>
>> [...]
>>
>> usort($a, "cmp_User");
>
> Thanks for example! What if sort direction and/or fields only known at
> runtime?

Besides Denis' solution, you could also write a comparer class, which
is, what I do:

abstract class RecordComparer {

const SortAscending = 1;
const SortDescending = -1;

protected $_direction;

public function __construct($direction) {
$this->_direction;
}

// Some basic methods to compare different datatypes
protected function _compareStringProperty($a, $b, $property) {
// I use strcoll here, because it's locale aware
return strcoll($a->{$property}, $b->{$property};
}

protected function _compareNumberProperty($a, $b, $property) {
return $a->{$property} - $b->{$property};
}

...
}

class UserComparer extends RecordComparer {

public function compareByFirstname(User $a, User $b) {
$result = $this->_compareStringProperty($a, $b, 'Firstname')
* $this->_direction;

// Sort by lastname, if firstname is equal:
if ($result === 0)
$result = $this->compareByLastname($a, $b);

return $result;
}

// ...implement a method for each property that should be sortable...
}

$a = array (
new User('Alice', 'Smith', '1960-01-01'),
new User('Michael', 'Jordan', '1950-01-01'),
new User('Kevin', 'Dilan', '1950-01-01'),
);

// The manual doesn't state this, but usort can also take instances of
// a class:
$comparer = new UserComparer(UserComparer::SortAscending);
usort($a, array($comparer, 'compareByLastname');
usort($a, array($ocmparer, 'compareByFirstname');
....

But I admit, this concept may not fit for you, if you want to decide
during runtime a complex sorting on multiple properties with varying
directions, like

Lastname ASC, Birthday DESC
or
Lastname ASC, Birthday ASC

It works, if you want to have something like this:

Sort by lastname, but if they are equal, automatically sort records with
equal lastnames by their birthdays, etc.

HTH, Helmut
[Message index]
 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: SNMPv3 for PHP?
Next Topic: Using server to list CSS page list in menu
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Sat Nov 23 05:36:49 GMT 2024

Total time taken to generate the page: 0.05980 seconds