Sorteer array van objecten op objectvelden

Hoe kan ik deze reeks objecten sorteren op een van de velden, zoals nameof 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
        )
   ....

Antwoord 1, autoriteit 100%

Gebruik usort, hier is een voorbeeld uit de handleiding:

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

Je kunt ook elke callableals tweede argument gebruiken . Hier zijn enkele voorbeelden:

  • Gebruik van anonieme functies(vanaf PHP 5.3)

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

     usort($your_data, array($this, "cmp")); // "cmp" should be a method in the class
    
  • Gebruik pijlfuncties(vanaf PHP 7.4)

     usort($your_data, fn($a, $b) => strcmp($a->name, $b->name));
    

Als u numerieke waarden vergelijkt, fn($a, $b) => $a->count - $b->countaangezien de “vergelijk”-functie het zou moeten doen, of, als u nog een andere manier wilt om hetzelfde te doen, vanaf PHP 7 kunt u de Ruimteschipoperator, als volgt: fn($a, $b) => $a->count <=> $b->count.


Antwoord 2, autoriteit 59%

Hier is een leukere manier om sluitingen te gebruiken

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

Let op: dit staat niet in de documentatie van PHP, maar als u 5.3+ gebruikt, worden sluitingen ondersteund waar aanroepbare argumenten kunnen worden opgegeven.


Antwoord 3, autoriteit 8%

Als u gehele waarden wilt sorteren:

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

GE-UPDATE
met de string vergeet niet te converteren naar hetzelfde register (hoger of lager)

// 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);
});

Antwoord 4, autoriteit 5%

als je php oop gebruikt, moet je misschien veranderen naar:

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')); 

Antwoord 5, autoriteit 4%

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

Dezelfde code komt voor in het veld count.

Meer details over usort: http://ru2.php.net/usort

Btw, waar heb je die array vandaan? Ik hoop dat dat niet uit de database komt?


Antwoord 6

U kunt deze functie gebruiken (werkt in PHP-versie >= 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;
        });
    }
}

Voorbeeld:

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)

Antwoord 7

Als alles mislukt, is hier een andere oplossing:

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

Antwoord 8

U kunt usortals volgt gebruiken:

usort($array,function($first,$second){
    return strcmp($first->name, $second->name);
});

Antwoord 9

Nadeel van alle antwoorden hier is dat ze statischeveldnamen gebruiken, dus ik heb een aangepaste versie in OOP-stijl geschreven. Ervan uitgaande dat u gettermethoden gebruikt, kunt u deze klasse rechtstreeks gebruiken en de veldnaam als parametergebruiken. Waarschijnlijk vindt iemand het nuttig.

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;
    }
} 

Antwoord 10

als je datums wilt sorteren

  usort($threads,function($first,$second){
        return strtotime($first->dateandtime) < strtotime($second->dateandtime);
    });

Antwoord 11

Als je een lokale stringvergelijking nodig hebt, kun je strcollin plaats van strcmp.

Denk eraan om eerst setlocalete gebruiken met LC_COLLATEom de lokale informatie in te stellen indien nodig.

 usort($your_data,function($a,$b){
    setlocale (LC_COLLATE, 'pl_PL.UTF-8'); // Example of Polish language collation
    return strcoll($a->name,$b->name);
  });

Antwoord 12

Een eenvoudig alternatief waarmee u dynamisch kunt bepalen op welk veld de sortering is gebaseerd:

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

Dit is gebaseerd op de Sluitingsklasse, die anonieme functies mogelijk maakt. Het is beschikbaar sinds PHP 5.3.


Antwoord 13

Als je dit binnen Codeigniter gebruikt, kun je de volgende methoden gebruiken:

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

@rmoney bedankt voor de suggestie. Het helpt me echt.


Antwoord 14

Bedankt voor de inspiratie, ik moest ook een externe $translator-parameter toevoegen

usort($listable_products, function($a, $b) {
    global $translator;
    return strcmp($a->getFullTitle($translator), $b->getFullTitle($translator));
});

Antwoord 15

Als u op slechts één veld hoeft te sorteren, dan is usorteen goede keuze. De oplossing wordt echter snel rommelig als u op meerdere velden moet sorteren. In dit geval kan de YaLinqo-bibliotheek* worden gebruikt, die SQL-achtige querysyntaxis voor arrays en objecten implementeert. Het heeft een mooie syntaxis voor alle gevallen:

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

Hier is '$v->count'een afkorting voor function ($v) { return $v->count; }(beide kunnen worden gebruikt). Deze methodeketens retourneren iterators, maar je kunt arrays krijgen door aan het einde ->toArray()toe te voegen als je het nodig hebt.

* door mij ontwikkeld


Antwoord 16

Je kunt gesorteerdfunctie van 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'));

Antwoord 17

Dit is wat ik heb voor een utility-klasse

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

Noem het:

Util::sortArrayByName($array, "array_property_name");

Antwoord 18

U kunt usort zo gebruiken

Als u op nummer wilt sorteren:

function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");

Of 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");

Zie meer: ​​https://www.php.net/manual/ nl/function.usor.php

Other episodes