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.
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
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.
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 );
Pour cette fonction de comparaison, vous pouvez simplement faire:
function cmp( $a, $b )
{
return $b->weight - $a->weight;
}
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.
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;
}
}
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');
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:
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'));