Сортировка объектов в PHP


Что такое элегантный способ сортировки объектов в PHP? Я бы с удовольствием сделал что-то подобное этому.

$sortedObjectArary = sort($unsortedObjectArray, $Object->weight);

В основном укажите массив, который я хочу отсортировать, а также поле, по которому я хочу выполнить сортировку. Я заглянул в сортировку многомерных массивов, и там может быть что-то полезное, но я не вижу ничего элегантного или очевидного.

Author: jW., 2008-09-24

10 answers

Почти дословно из руководства:

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

 73
Author: Kent Fredric, 2014-10-11 11:52:52

Для php>=5.3

function osort(&$array, $prop)
{
    usort($array, function($a, $b) use ($prop) {
        return $a->$prop > $b->$prop ? 1 : -1;
    }); 
}

Обратите внимание, что при этом используются анонимные функции/замыкания. Возможно, вам будет полезно ознакомиться с документами php по этому вопросу.

 20
Author: Will Shaver, 2009-08-24 00:07:27

Вы даже можете встроить поведение сортировки в класс, который вы сортируете, если вам нужен такой уровень контроля

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 );
 5
Author: Peter Bailey, 2008-09-23 23:01:14

Для этой функции сравнения вы можете просто сделать:

function cmp( $a, $b )
{ 
    return $b->weight - $a->weight;
} 
 4
Author: Tom, 2011-01-05 20:13:45

Функция 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");

Обратите внимание, что любые ключи массива будут потеряны.

 2
Author: Adam Wright, 2008-09-23 22:22:03

Вы можете использовать функцию 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;
    }
}
 1
Author: Jeremy Ruten, 2008-09-23 22:22:31

В зависимости от проблемы, которую вы пытаетесь решить, вы также можете найти интерфейсы SPL полезными. Например, реализация интерфейса ArrayAccess позволит вам получить доступ к вашему классу как к массиву. Кроме того, реализация интерфейса seekableIterator позволит вам выполнять циклический просмотр объекта точно так же, как массива. Таким образом, вы можете сортировать свой объект так же, как если бы он был простым массивом, имея полный контроль над значениями, которые он возвращает для данного ключа.

Для большего подробности:

 0
Author: Wilco, 2008-09-24 02:22:58
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;

}

Например, =>

$myAscSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'asc');

$myDescSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'desc');
 0
Author: biswarupadhikari, 2012-06-12 05:05:20

У вас может быть почти тот же код, который вы опубликовали с помощью отсортированной функции из 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'));
 0
Author: Ihor Burlachenko, 2016-02-24 20:42:42

Если вы хотите изучить полный (ужасающий) объем функций в стиле лямбда в PHP, см.: http://docs.php.net/manual/en/function.create-function.php

 -3
Author: Internet Friend, 2008-09-23 22:27:34