2008-09-23 11 views
42

¿Qué es una forma elegante de ordenar objetos en PHP? Me encantaría lograr algo similar a esto.Ordenar Objeto en PHP

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

Especifique básicamente la matriz que quiero ordenar, así como el campo que quiero ordenar. Analicé la ordenación de matrices multidimensionales y podría haber algo útil allí, pero no veo nada elegante u obvio.

Respuesta

73

casi literalmente de manual:

function compare_weights($a, $b) { 
    if($a->weight == $b->weight) { 
     return 0; 
    } 
    return ($a->weight < $b->weight) ? -1 : 1; 
} 

usort($unsortedObjectArray, 'compare_weights'); 

Si desea que los objetos sean capaces de ordenar los mismos, véase el ejemplo 3 aquí: http://php.net/usort

+0

Ese tercer ejemplo es básicamente diciendo: "Lo siento no hay manera estándar para que un objeto tener un comparador, simplemente escriba una función estática 'cmp_obj' en el objeto, y recuerde llamar a la orden de servicio con esa función." De acuerdo, excepto que cmp_obj no tiene un significado especial en PHP. Quizás eso sería útil si PHP tuviera algo así como la función '__cmp__' de Python como estándar, o la interfaz' implementa Comparable' de Java para que pueda ordenar y usar '<', '>', comparadores sin profundizar en la implementación de esa clase que quiera que sea el género. Desafortunadamente, parece que esto tampoco está cambiando en PHP7. – NoBugs

+1

Ahora, eso haría que PHP fuera sensato y usable, no puede tener eso, ¿verdad? :) –

+0

No, no podemos, pero realmente necesitamos otra forma de expresar la misma expresión en PHP7 aunque https://wiki.php.net/rfc/combined-comparison-operator – NoBugs

2

La función usort (http://uk.php.net/manual/en/function.usort.php) es su amigo. Algo así como ...

function objectWeightSort($lhs, $rhs) 
{ 
    if ($lhs->weight == $rhs->weight) 
    return 0; 

    if ($lhs->weight > $rhs->weight) 
    return 1; 

    return -1; 
} 

usort($unsortedObjectArray, "objectWeightSort"); 

Tenga en cuenta que se perderán las teclas de matriz.

1

Puede usar la función usort() y hacer su propia función de comparación.

$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

incluso se puede construir el comportamiento de la clasificación en la clase que estés clasificación, si quiere ese nivel de control

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

Esta solución no funciona en PHP4. – Lobo

+18

@Lobo PHP 5 ya tenía 4 años en el momento en que escribí esto, que fue hace 4 años. Creo que después de 8 años, podemos poner PHP4 a pastar. –

0

Dependiendo del problema que intenta resolver, también se pueden encontrar las interfaces de SPL útil. Por ejemplo, la implementación de la interfaz ArrayAccess le permitiría acceder a su clase como una matriz. Además, la implementación de la interfaz SeekableIterator le permite recorrer su objeto como una matriz. De esta forma, podría ordenar su objeto como si fuera una matriz simple, teniendo control total sobre los valores que devuelve para una clave determinada.

Para más detalles:

20

para PHP> = 5,3

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

Tenga en cuenta que este utiliza Ano nimias funciones/cierres. Puede encontrar la revisión de los documentos php en ese útil.

+1

¿Qué pasa si '$ a -> $ prop == $ b -> $ prop'? –

4

Por esa función de comparación, sólo se puede hacer:

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; 

} 

correo.g =>

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

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

Usted puede tener casi el mismo código que informado con sorted función de 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'));