首页 文章

按对象字段对对象数组进行排序

提问于
浏览
428

如何通过其中一个字段(如 namecount )对此对象数组进行排序?

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 回答

  • 2

    如果您只需要按一个字段排序,那么 usort 是一个不错的选择 . 但是,如果需要按多个字段排序,解决方案很快就会变得混乱 . 在这种情况下,可以使用YaLinqo library *,它为数组和对象实现类似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() 来获取数组 .

    *由我开发

  • 38

    这就是我对实用程序类的看法

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

    Call it:

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

    继承人使用闭包更好的方式

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

    请注意,这不在PHP的文档中,但如果您使用5.3闭包,则可以提供可调用的参数 .

  • 1

    如果需要基于本地的字符串比较,则可以使用strcoll而不是 strcmp .

    记得首先使用setlocaleLC_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);
      });
    
  • 1

    如果你想排序日期

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

    您可以使用此功能(适用于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)
    
  • 24

    如果一切都失败了,这是另一个解

    $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

    如果您使用的是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'));
    
  • 1

    如果要排序整数值:

    // 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 用字符串别忘了转换到同一个寄存器(上面或下面)

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

    您可以使用 usort ,如下所示:

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

    最简单的方法是

    return array_values(array_sort($array, function ($value) {
      return $value->key;
    }));
    

    将钥匙替换为您要订购的“钥匙”

  • 0
    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

    一个简单的替代方案,允许您动态确定排序所基于的字段:

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

    这基于Closure class,它允许匿名功能 . 从PHP 5.3开始提供 .

  • 1

    如果您在Codeigniter中使用它,您可以使用以下方法:

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

    @rmooney谢谢你的建议 . 这对我很有帮助 .

  • 24

    感谢您的灵感,我还必须添加一个外部$ translator参数

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

    您可以使用Nspl中的sorted函数:

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

    使用usort,这是一个改编自手册的例子:

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

    从评论中导入的编辑:

    如果您正在从类内部对数组进行排序,并且您的排序函数 cmp 也在类中定义,那么使用:

    usort($your_data, array($this, "cmp"))
    
  • 0

    这里所有答案的缺点是他们使用 static 字段名称,所以我用OOP风格编写了一个调整后的版本 . 假设您使用的是getter方法,您可以直接使用此类并使用 field name as parameter . 可能有人发现它很有用 .

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

相关问题