web-dev-qa-db-fra.com

Trier l'objet dans PHP

Quel est un moyen élégant de trier des objets en PHP? J'aimerais accomplir quelque chose de semblable à ceci.

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

En gros, spécifiez le tableau que je veux trier ainsi que le champ sur lequel je veux trier. Je me suis penché sur le tri multidimensionnel et il pourrait y avoir quelque chose d’utile, mais je ne vois rien d’élégant ou d’évident.

42
jW.

Presque textuellement du manuel: 

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

usort($unsortedObjectArray, 'compare_weights');

Si vous voulez que les objets puissent se trier eux-mêmes, voyez l'exemple 3 ici: http://php.net/usort

73
Kent Fredric

Pour php> = 5.3

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

Notez que cela utilise des fonctions/fermetures anonymes. Vous trouverez peut-être utile de consulter les documents php sur cette documentation.

20
Will Shaver

Vous pouvez même intégrer le comportement de tri dans la classe que vous triez, si vous voulez ce niveau de contrôle

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
Peter Bailey

Pour cette fonction de comparaison, vous pouvez simplement faire:

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

La fonction usort ( http://fr.php.net/manual/en/function.usort.php ) est votre ami. Quelque chose comme...

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

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

   return -1;
}

usort($unsortedObjectArray, "objectWeightSort");

Notez que toutes les clés de tableau seront perdues.

2
Adam Wright

Vous pouvez utiliser la fonction usort () et créer votre propre fonction de comparaison.

$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
Jeremy Ruten
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;

}

par exemple =>

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

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

En fonction du problème que vous essayez de résoudre, vous pouvez également trouver les interfaces SPL utiles. Par exemple, implémenter l'interface ArrayAccess vous permettrait d'accéder à votre classe comme un tableau. En outre, l'implémentation de l'interface SeekableIterator vous permettrait de parcourir votre objet comme un tableau. De cette façon, vous pouvez trier votre objet comme s'il s'agissait d'un tableau simple, en contrôlant entièrement les valeurs qu'il renvoie pour une clé donnée.

Pour plus de détails:

0
Wilco

Vous pouvez avoir presque le même code que vous avez posté avec trié fonction 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'));
0
Ihor Burlachenko