2010-11-26 3 views
377

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

    .... 

ответ

498

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

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

usort($your_data, "cmp"); 

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

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

usort($your_data, array($this, "cmp")) 
22
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

Btw, где вы получите, что массив из? Надеюсь, что не из базы данных?

+0

На самом деле `$ result` будет содержать` true`, если он успешен, и ваше сравнение должно быть `$ a-> name> $ b-> name`. :) – cambraca 2010-11-26 03:56:48

+1

@cambraca: Ох, забыл, что принимает массив по ссылке. Btw, OP не сказал, какой порядок ему нужен для сортировки коллекции. – zerkms 2010-11-26 03:57:49

+0

ну да, это база данных :) фактически из функции, которая получает данные из базы данных – Alex 2010-11-26 04:01:55

371

Heres более приятный способ использования укупорочные

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

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

36

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

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

Если вам нужна локальная на основе сравнения строк, вы можете использовать strcoll вместо strcmp.

Учетная запись для первого использования setlocale с LC_COLLATE для установки информации о локали в случае необходимости.

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

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

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

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

0

Если вам нужно отсортировать только по одному полю, тогда usort - хороший выбор. Однако решение быстро становится беспорядочным, если вам нужно сортировать по нескольким полям. В этом случае может использоваться библиотека YaLinqo *, которая реализует SQL-подобный синтаксис запросов для массивов и объектов. Он имеет довольно синтаксис для всех случаев:

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

Здесь '$v->count' является обобщающим для function ($v) { return $v->count; } (либо могут быть использованы). Эти цепочки методов возвращают итераторы, но вы можете получить массивы, добавив в конце ->toArray(), если вам это нужно.

* разработан мной

1

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

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

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

Спасибо за вдохновения, я также должен добавить параметр переводчика внешнего $

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

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

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

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

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

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

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

$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; 
Смежные вопросы