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

时间:2010-11-26 03:50:57

标签: php arrays sorting object

如何按其中一个字段对此对象数组进行排序,例如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
        )

   ....

21 个答案:

答案 0 :(得分:601)

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

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

usort($your_data, "cmp");

从评论中导入的

编辑:

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

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

答案 1 :(得分:439)

使用闭包更好的方法

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

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

答案 2 :(得分:40)

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

答案 3 :(得分:36)

如果要对整数值进行排序:

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

答案 4 :(得分:26)

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

顺便问一下,你从哪里得到那个阵列?我希望不是来自数据库?

答案 5 :(得分:8)

您可以使用此功能(适用于PHP版本&gt; = 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)

答案 6 :(得分:4)

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

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

答案 7 :(得分:2)

这里所有答案的缺点是它们使用静态字段名称,所以我用OOP样式编写了一个调整后的版本。假设您使用的是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;
    }
} 

答案 8 :(得分:2)

如果一切都失败了,这是另一种解决方案:

restrict

答案 9 :(得分:1)

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

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

答案 10 :(得分:1)

如果您在Codeigniter中使用此功能,则可以使用以下方法:

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

@rmooney感谢您的建议。这对我很有帮助。

答案 11 :(得分: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);
  });

答案 12 :(得分:1)

一个简单的替代方法,使您可以动态确定排序所基于的字段:

$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起可用。

答案 13 :(得分: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()来获取数组。

*由我开发

答案 14 :(得分: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'));

答案 15 :(得分:0)

如果要对日期进行排序

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

答案 16 :(得分:0)

这是我为实用程序类所拥有的

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

调用:

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

答案 17 :(得分:0)

您可以像这样使用usort

如果要按数字排序:

function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$a = array(3, 2, 5, 6, 1);

usort($a, "cmp");

或Abc字符:

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

查看更多:https://www.php.net/manual/en/function.usort.php

答案 18 :(得分:0)

Demodave关于食用多键的参考答案

 function array_sort_by(array $arr, $keys){

    if(!is_array($keys))
        $keyList = explode(',', $keys);
    $keyList = array_keys(array_flip($keyList)); // array_unique 
    $keyList = array_reverse($keyList);

    $result = &$arr;
    foreach ($keyList as $key) {
        if(array_key_exists($key, $arr))
            $result = usort($result, function($a, $b) use ($key) { return strcmp($a->{$key}, $b->{$key}); });
    }
    return $result;
}

答案 19 :(得分:0)

$array[0] = array('key_a' => 'z', 'key_b' => 'c');
$array[1] = array('key_a' => 'x', 'key_b' => 'b');
$array[2] = array('key_a' => 'y', 'key_b' => 'a');

function build_sorter($key) {
    return function ($a, $b) use ($key) {
        return strnatcmp($a[$key], $b[$key]);
    };
}

usort($array, build_sorter('key_b'));

答案 20 :(得分:-2)

最好的简单方法是

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

用您要订购的“钥匙”代替钥匙