2008-09-23 2 views
42

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

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

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

ответ

73

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

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

+0

Это третий пример, в основном говорят, «К сожалению нет никакого стандартного способа для объекта есть компаратор, просто напишите статическую функцию `cmp_obj` в объекте и не забудьте вызвать функцию с этой функцией." Хорошо, за исключением того, что cmp_obj не имеет особого значения в PHP. Возможно, это было бы полезно, если бы PHP имел что-то вроде функции «__cmp__» Python в качестве стандартного, или интерфейс «реализует Comparable» Java, чтобы он мог сортировать и использовать `<`, `>`, компараторы, не копаясь в том, что реализация этого класса хочет, чтобы сортировка была. К сожалению, похоже, что это тоже не меняется в PHP7. – NoBugs 2015-08-17 04:13:33

+1

Теперь, что сделало бы PHP разумным и полезным, не может это иметь? :) – 2015-08-17 04:19:46

+0

Нет, мы не можем, но нам действительно нужен другой способ выразить одно и то же выражение в PHP7, хотя https://wiki.php.net/rfc/combined-comparison-operator – NoBugs 2015-08-17 04:27:36

2

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

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

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

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

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

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

20

Для PHP> = 5,3

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

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

4

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

function cmp($a, $b) 
{ 
    return $b->weight - $a->weight; 
} 
0
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

Вы можете иметь почти тот же код, как вы писали с 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')); 
Смежные вопросы