Trier tableau d'objets par champs d'objet

Comment puis-je trier ce tableau d'objets par l'un de ses champs, comme name ou count ?

  Array
(
    [0] => stdClass Object
        (
            [ID] => 1
            [name] => Mary Jane
            [count] => 420
        )

    [1] => stdClass Object
        (
            [ID] => 2
            [name] => Johnny
            [count] => 234
        )

    [2] => stdClass Object
        (
            [ID] => 3
            [name] => Kathy
            [count] => 4354
        )

   ....
418
demandé sur Alex 2010-11-26 06:50:56

17 réponses

Use usort , Voici un exemple adapté du manuel:

function cmp($a, $b)
{
    return strcmp($a->name, $b->name);
}

usort($your_data, "cmp");

modifications importées à partir des commentaires:

Si vous triez le tableau à l'intérieur de la classe et que votre fonction de tri cmp est également définie à l'intérieur de la classe, utilisez ceci:

usort($your_data, array($this, "cmp"))
557
répondu cambraca 2015-11-16 23:25:26

Voici une meilleure façon d'utiliser des fermetures

usort($your_data, function($a, $b)
{
    return strcmp($a->name, $b->name);
});

Veuillez noter que ce n'est pas dans la documentation de PHP mais si vous utilisez 5.3+ closures sont pris en charge où les arguments appelables peuvent être fournis.

407
répondu Scott Quinlan 2012-04-15 04:31:17

Si vous utilisez php oop, vous devrez peut-être changer pour:

public static function cmp($a, $b) 
{
    return strcmp($a->name, $b->name);
}

//in this case FUNCTION_NAME would be cmp
usort($your_data, array('YOUR_CLASS_NAME','FUNCTION_NAME')); 
38
répondu Doron Segal 2014-07-10 11:38:19
usort($array, 'my_sort_function');

var_dump($array);

function my_sort_function($a, $b)
{
    return $a->name < $b->name;
}

Le même code sera avec le count champ.

Plus de détails sur usort: http://ru2.php.net/usort

Btw, d'où Avez-vous eu ce tableau? J'espère que pas de base de données?

23
répondu zerkms 2010-11-26 03:58:15

Si vous voulez trier les valeurs entières:

// Desc sort
usort($array,function($first,$second){
    return $first->number < $second->number;
});

// Asc sort
usort($array,function($first,$second){
    return $first->number > $second->number;
});

Mise à jour avec la chaîne, n'oubliez pas de convertir au même registre (supérieur ou inférieur)

// Desc sort
usort($array,function($first,$second){
    return strtolower($first->text) < strtolower($second->text);
});

// Asc sort
usort($array,function($first,$second){
    return strtolower($first->text) > strtolower($second->text);
});
23
répondu Roman Yakoviv 2018-01-17 11:32:24

Vous pouvez utiliser cette fonction (fonctionne en version PHP > = 5.3):

function sortArrayByKey(&$array,$key,$string = false,$asc = true){
    if($string){
        usort($array,function ($a, $b) use(&$key,&$asc)
        {
            if($asc)    return strcmp(strtolower($a{$key}), strtolower($b{$key}));
            else        return strcmp(strtolower($b{$key}), strtolower($a{$key}));
        });
    }else{
        usort($array,function ($a, $b) use(&$key,&$asc)
        {
            if($a[$key] == $b{$key}){return 0;}
            if($asc) return ($a{$key} < $b{$key}) ? -1 : 1;
            else     return ($a{$key} > $b{$key}) ? -1 : 1;

        });
    }
}

Exemple:

sortArrayByKey($yourArray,"name",true); //String sort (ascending order)
sortArrayByKey($yourArray,"name",true,false); //String sort (descending order)
sortArrayByKey($yourArray,"id"); //number sort (ascending order)
sortArrayByKey($yourArray,"count",false,false); //number sort (descending order)
8
répondu PoengAlex 2017-06-20 13:40:04

Vous pouvez utiliser usort, comme ceci:

usort($array,function($first,$second){
    return strcmp($first->name, $second->name);
});
3
répondu Luca C. 2017-09-20 09:04:58

L'inconvénient de toutes les réponses ici est qu'elles utilisent des noms de champsstatiques , donc j'ai écrit une version ajustée dans le style POO. Supposé que vous utilisez des méthodes getter, vous pouvez utiliser directement cette classe et utiliser le nom de Champ comme paramètre . Probablement quelqu'un le trouve utile.

class CustomSort{

    public $field = '';

    public function cmp($a, $b)
    {
        /**
         * field for order is in a class variable $field
         * using getter function with naming convention getVariable() we set first letter to uppercase
         * we use variable variable names - $a->{'varName'} would directly access a field
         */
        return strcmp($a->{'get'.ucfirst($this->field)}(), $b->{'get'.ucfirst($this->field)}());
    }

    public function sortObjectArrayByField($array, $field)
    {
        $this->field = $field;
        usort($array, array("Your\Namespace\CustomSort", "cmp"));;
        return $array;
    }
} 
2
répondu Horst Jahns 2015-06-20 17:33:03

Si tout échoue, voici une autre solution:

$names = array(); 
foreach ($my_array as $my_object) {
    $names[] = $my_object->name; //any object field
}

array_multisort($names, SORT_ASC, $my_array);

return $my_array;
2
répondu Adrian P. 2017-11-22 17:48:04

Si vous avez besoin d'une comparaison de chaînes locale, vous pouvez utiliser strcoll au lieu de strcmp.

Rappelez-vous la première utilisation setlocale avec LC_COLLATE pour définir les paramètres régionaux d'information si nécessaire.

  usort($your_data,function($a,$b){
    setlocale (LC_COLLATE, 'pl_PL.UTF-8'); // Example of Polish language collation
    return strcoll($a->name,$b->name);
  });
1
répondu Wilq 2013-07-05 12:51:16

Si vous utilisez ceci dans Codeigniter, vous pouvez utiliser les méthodes:

usort($jobs, array($this->job_model, "sortJobs"));  // function inside Model
usort($jobs, array($this, "sortJobs")); // Written inside Controller.

@rmooney merci pour la suggestion. Ça m'aide vraiment.

1
répondu PHP Developer 2014-08-06 09:31:37

Merci pour les inspirations, j'ai aussi dû ajouter un paramètre externe $ translator

usort($listable_products, function($a, $b) {
    global $translator;
    return strcmp($a->getFullTitle($translator), $b->getFullTitle($translator));
});
1
répondu michalzuber 2016-06-07 14:39:30

Une alternative simple qui vous permet de déterminer dynamiquement le champ sur lequel le tri est basé:

$order_by = 'name';
usort($your_data, function ($a, $b) use ($order_by)
{
    return strcmp($a->{$order_by}, $b->{$order_by});
});

Ceci est basé sur la classe de fermeture , qui permet des fonctions anonymes. Il est disponible depuis PHP 5.3.

1
répondu clami219 2018-06-29 16:18:55

Si vous avez besoin de trier par un seul champ, puis usort est un bon choix. Cependant, la solution devient rapidement désordonnée si vous devez Trier par plusieurs champs. Dans ce cas, yalinqo library * peut être utilisé, ce qui implémente une syntaxe de requête de type SQL pour les tableaux et les objets. Il a une jolie syntaxe pour tous les cas:

$sortedByName         = from($objects)->orderBy('$v->name');
$sortedByCount        = from($objects)->orderBy('$v->count');
$sortedByCountAndName = from($objects)->orderBy('$v->count')->thenBy('$v->name');

Ici '$v->count' est un raccourci pour function ($v) { return $v->count; } (peuvent être utilisés). Ces chaînes de méthodes renvoient des itérateurs, mais vous pouvez obtenir des tableaux en ajoutant ->toArray() à la fin si vous en avez besoin il.

* développé par moi

0
répondu Athari 2015-06-04 00:58:14

Vous pouvez utiliser triés la fonction de Nspl:

use function \nspl\a\sorted;
use function \nspl\op\propertyGetter;
use function \nspl\op\methodCaller;

// Sort by property value
$sortedByCount = sorted($objects, propertyGetter('count'));

// Or sort by result of method call
$sortedByName = sorted($objects, methodCaller('getName'));
0
répondu Ihor Burlachenko 2016-02-24 20:39:30

Si vous voulez trier les dates

   usort($threads,function($first,$second){
        return strtotime($first->dateandtime) < strtotime($second->dateandtime);
    });
0
répondu Nicolas Giszpenc 2018-04-19 20:24:36

C'est Ce que j'ai pour une classe utilitaire

class Util
{
    public static function sortArrayByName(&$arrayToSort, $meta) {
        usort($arrayToSort, function($a, $b) use ($meta) {
            return strcmp($a[$meta], $b[$meta]);
        });
    }
}

Appelez-le:

Util::sortArrayByName($array, "array_property_name");
0
répondu Demodave 2018-09-27 17:26:57