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

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

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

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

Ответ 1

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

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

Ответ 2

Для php >= 5.3

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

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

Ответ 3

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

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 );

Ответ 4

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

function cmp( $a, $b )
{ 
    return $b->weight - $a->weight;
} 

Ответ 5

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

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

Ответ 6

Вы можете использовать функцию 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;
    }
}

Ответ 7

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

Подробнее:

Ответ 8

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;

}

e.g = >

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

$myDescSortedArrayObject=PHPArrayObjectSorter($unsortedarray,$totalMarks,'desc');

Ответ 9

Вы можете иметь почти тот же код, что и вы, с sorted функцией 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'));