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
|