Сортировать массив объектов по полям объекта - PullRequest
462 голосов
/ 26 ноября 2010

Как мне отсортировать этот массив объектов по одному из его полей, например name или 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
        )

   ....

Ответы [ 18 ]

615 голосов
/ 26 ноября 2010

Используйте usort , вот пример, адаптированный из руководства:

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

usort($your_data, "cmp");

правки, импортированные из комментариев:

ЕслиВы сортируете массив изнутри класса, и ваша функция сортировки cmp также определена внутри класса, затем используйте это:

usort($your_data, array($this, "cmp"))
446 голосов
/ 15 апреля 2012

Вот более приятный способ использования замыканий

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

Обратите внимание, что этого нет в документации PHP, но если вы используете замыкания 5.3+, то поддерживаются вызываемые аргументы.

40 голосов
/ 22 января 2013

если вы используете php oop, вам может потребоваться изменить на:

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 голосов
/ 20 сентября 2017

Если вы хотите отсортировать целочисленные значения:

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

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

ОБНОВЛЕНО со строкой, не забудьте преобразовать в тот же регистр (верхний или нижний)

// 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);
});
26 голосов
/ 26 ноября 2010
usort($array, 'my_sort_function');

var_dump($array);

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

Тот же код будет с полем count.

Подробнее о usort: http://ru2.php.net/usort

Кстати, откуда вы взяли этот массив? Я надеюсь, что не из базы данных?

8 голосов
/ 05 октября 2016

Вы можете использовать эту функцию (работает в версии 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;

        });
    }
}

Пример:

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)
4 голосов
/ 31 августа 2017

Вы можете использовать usort, например:

usort($array,function($first,$second){
    return strcmp($first->name, $second->name);
});
3 голосов
/ 20 июня 2015

Недостатком всех ответов здесь является то, что они используют статические имена полей, поэтому я написал исправленную версию в стиле ООП.Предполагая, что вы используете методы получения, вы можете напрямую использовать этот класс и использовать имя поля в качестве параметра .Возможно, кто-то найдет это полезным.

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 голосов
/ 22 ноября 2017

Если все не получается, вот другое решение:

$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;
1 голос
/ 20 февраля 2014

Если вы используете это внутри Codeigniter, вы можете использовать методы:

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

@ rmooney спасибо за предложение. Это действительно помогает мне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...