Каков элегантный способ сортировки объектов в PHP? Я хотел бы сделать что-то похожее на это.
$sortedObjectArary = sort($unsortedObjectArray, $Object->weight);
В основном укажите массив, который я хочу сортировать, а также поле, которое я хочу сортировать. Я посмотрел на многомерную сортировку массива, и там может быть что-то полезное, но я не вижу ничего элегантного или очевидного.
Почти дословно из руководства:
function compare_weights($a, $b) { if($a->weight == $b->weight) { return 0; } return ($a->weight < $b->weight) ? -1 : 1; } usort($unsortedObjectArray, 'compare_weights');
Если вы хотите, чтобы объекты могли сортировать себя, см. Пример 3 здесь: http://php.net/usort
Для php> = 5.3
function osort(&$array, $prop) { usort($array, function($a, $b) use ($prop) { return $a->$prop > $b->$prop ? 1 : -1; }); }
Обратите внимание, что это использует анонимные функции / закрытия. Можете найти обзор документов php на этом полезном.
Вы даже можете создать поведение сортировки в классе, который вы сортируете, если вы хотите, чтобы этот уровень контроля
class thingy { public $prop1; public $prop2; static $sortKey; public function __construct( $prop1, $prop2 ) { $this->prop1 = $prop1; $this->prop2 = $prop2; } public static function sorter( $a, $b ) { return strcasecmp( $a->{self::$sortKey}, $b->{self::$sortKey} ); } public static function sortByProp( &$collection, $prop ) { self::$sortKey = $prop; usort( $collection, array( __CLASS__, 'sorter' ) ); } } $thingies = array( new thingy( 'red', 'blue' ) , new thingy( 'apple', 'orange' ) , new thingy( 'black', 'white' ) , new thingy( 'democrat', 'republican' ) ); print_r( $thingies ); thingy::sortByProp( $thingies, 'prop1' ); print_r( $thingies ); thingy::sortByProp( $thingies, 'prop2' ); print_r( $thingies );
Для этой функции сравнения вы можете просто сделать:
function cmp( $a, $b ) { return $b->weight - $a->weight; }
Функция usort ( http://uk.php.net/manual/en/function.usort.php ) является вашим другом. Что-то вроде…
function objectWeightSort($lhs, $rhs) { if ($lhs->weight == $rhs->weight) return 0; if ($lhs->weight > $rhs->weight) return 1; return -1; } usort($unsortedObjectArray, "objectWeightSort");
Обратите внимание, что любые ключи массива будут потеряны.
Вы можете использовать функцию usort () и создать собственную функцию сравнения.
$sortedObjectArray = usort($unsortedObjectArray, 'sort_by_weight'); function sort_by_weight($a, $b) { if ($a->weight == $b->weight) { return 0; } else if ($a->weight < $b->weight) { return -1; } else { return 1; } }
В зависимости от проблемы, которую вы пытаетесь решить, вы также можете найти полезные интерфейсы SPL. Например, реализация интерфейса ArrayAccess позволит вам получить доступ к вашему классу, например массиву. Кроме того, реализация интерфейса SeekableIterator позволит вам проходить через ваш объект точно так же, как массив. Таким образом, вы можете сортировать свой объект так же, как если бы это был простой массив, имеющий полный контроль над значениями, которые он возвращает для заданного ключа.
Больше подробностей:
function PHPArrayObjectSorter($array,$sortBy,$direction='asc') { $sortedArray=array(); $tmpArray=array(); foreach($this->$array as $obj) { $tmpArray[]=$obj->$sortBy; } if($direction=='asc'){ asort($tmpArray); }else{ arsort($tmpArray); } foreach($tmpArray as $k=>$tmp){ $sortedArray[]=$array[$k]; } return $sortedArray; }
поfunction PHPArrayObjectSorter($array,$sortBy,$direction='asc') { $sortedArray=array(); $tmpArray=array(); foreach($this->$array as $obj) { $tmpArray[]=$obj->$sortBy; } if($direction=='asc'){ asort($tmpArray); }else{ arsort($tmpArray); } foreach($tmpArray as $k=>$tmp){ $sortedArray[]=$array[$k]; } return $sortedArray; }
eg =>
$myAscSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'asc'); $myDescSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'desc');
по$myAscSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'asc'); $myDescSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'desc');
Вы можете иметь почти тот же код, что и вы, с отсортированной функцией от Nspl :
use function \nspl\a\sorted; use function \nspl\op\propertyGetter; use function \nspl\op\methodCaller; // Sort by property value $sortedByWeight = sorted($objects, propertyGetter('weight')); // Or sort by result of method call $sortedByWeight = sorted($objects, methodCaller('getWeight'));
Если вы хотите изучить полную (ужасающую) степень функций лямбда-стиля в PHP, см. http://docs.php.net/manual/en/function.create-function.php