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
)
....
Utilisez usort , voici un exemple adapté du manuel:
function cmp($a, $b)
{
return strcmp($a->name, $b->name);
}
usort($your_data, "cmp");
éditions importées des commentaires:
Si vous triez le tableau de 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"))
Voici un moyen plus agréable d'utiliser des fermetures
usort($your_data, function($a, $b)
{
return strcmp($a->name, $b->name);
});
Veuillez noter que ceci ne se trouve pas dans la documentation de PHP, mais si vous utilisez 5.3 +, les fermetures sont prises en charge et vous pouvez fournir des arguments appelables.
si vous utilisez php oop, vous devrez peut-être passer à:
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'));
Si vous souhaitez 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;
});
UPDATED avec la chaîne ne pas oublier de convertir dans le 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);
});
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 champ count
.
Plus de détails sur usort
: http://ru2.php.net/usort
Btw, où avez-vous obtenu ce tableau? J'espère que pas de base de données?
Vous pouvez utiliser cette fonction (fonctionne sous PHP Version> = 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)
Vous pouvez utiliser usort
, comme ceci:
usort($array,function($first,$second){
return strcmp($first->name, $second->name);
});
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;
L’inconvénient de toutes les réponses ici est qu’elles utilisent les noms static field, j’ai donc écrit une version ajustée dans le style OOP. En supposant que vous utilisez des méthodes getter, vous pouvez directement utiliser cette classe et utiliser le nom du champ en tant que paramètre . Probablement que quelqu'un trouve cela 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;
}
}
Une alternative simple qui vous permet de déterminer dynamiquement le champ sur lequel est basé le tri:
$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 Closure , qui autorise les fonctions anonymes. Il est disponible depuis PHP 5.3.
Merci pour les inspirations, je devais aussi ajouter un paramètre externe du traducteur
usort($listable_products, function($a, $b) {
global $translator;
return strcmp($a->getFullTitle($translator), $b->getFullTitle($translator));
});
Si vous avez besoin d'une comparaison de chaînes locale, vous pouvez utiliser strcoll
au lieu de strcmp
.
N'oubliez pas d'utiliser d'abord setlocale
with LC_COLLATE
pour définir les informations de paramètres régionaux, 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);
});
Si vous utilisez ceci dans Codeigniter, vous pouvez utiliser les méthodes suivantes:
usort($jobs, array($this->job_model, "sortJobs")); // function inside Model
usort($jobs, array($this, "sortJobs")); // Written inside Controller.
@rmooney merci pour la suggestion. Cela m'aide vraiment.
C'est ce que j'ai pour une classe d'utilitaire
class Util
{
public static function sortArrayByName(&$arrayToSort, $meta) {
usort($arrayToSort, function($a, $b) use ($meta) {
return strcmp($a[$meta], $b[$meta]);
});
}
}
Appeler:
Util::sortArrayByName($array, "array_property_name");
Si vous avez besoin de trier par un seul champ, alors usort
est un bon choix. Cependant, la solution devient vite compliquée si vous devez trier plusieurs champs. Dans ce cas, vous pouvez utiliser YaLinqo library *, 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');
'$v->count'
est ici un raccourci pour function ($v) { return $v->count; }
(l'un ou l'autre peut être utilisé). Ces chaînes de méthodes renvoient des itérateurs, mais vous pouvez obtenir des tableaux en ajoutant finalement ->toArray()
si vous en avez besoin.
* développé par moi
le meilleur moyen simple est
return array_values(array_sort($array, function ($value) {
return $value->key;
}));
Remplacez la clé par la clé que vous souhaitez commander
si vous voulez trier les dates
usort($threads,function($first,$second){
return strtotime($first->dateandtime) < strtotime($second->dateandtime);
});
Vous pouvez utiliser trié 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'));
Vous pouvez utiliser usort comme ceci
Si vous souhaitez trier par numéro:
function cmp($a, $b)
{
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
ou Abc char:
function cmp($a, $b)
{
return strcmp($a["fruit"], $b["fruit"]);
}
$fruits[0]["fruit"] = "lemons";
$fruits[1]["fruit"] = "apples";
$fruits[2]["fruit"] = "grapes";
usort($fruits, "cmp");