Сортировать объект в PHP - PullRequest
       40

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

43 голосов
/ 24 сентября 2008

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

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

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

Ответы [ 10 ]

73 голосов
/ 24 сентября 2008

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

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

20 голосов
/ 24 августа 2009

для php> = 5.3

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

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

5 голосов
/ 24 сентября 2008

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

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 голосов
/ 05 января 2011

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

function cmp( $a, $b )
{ 
    return $b->weight - $a->weight;
} 
2 голосов
/ 24 сентября 2008

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

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

1 голос
/ 24 сентября 2008

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

Вы можете иметь почти такой же код, как вы отправили с отсортированной функцией из 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 голосов
/ 12 июня 2012
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 голосов
/ 24 сентября 2008

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

Для более подробной информации:

0 голосов
/ 24 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...