Php 按对象字段对对象数组排序

Php 按对象字段对对象数组排序,php,arrays,sorting,object,Php,Arrays,Sorting,Object,如何按照对象数组的某个字段(如name或count)对该数组进行排序 Array ( [0] => stdClass Object ( [ID] => 1 [name] => Mary Jane [count] => 420 ) [1] => stdClass Object ( [ID] => 2

如何按照对象数组的某个字段(如
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
        )

   ....
usort($array,'my_sort_function');
变量转储($数组);
函数my_sort_函数($a,$b)
{
返回$a->name<$b->name;
}
count
字段将使用相同的代码

有关usort的更多详细信息:

顺便说一句,你从哪里得到的数组?我希望不是来自数据库?

使用,下面是一个改编自手册的示例:

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

usort($your_data, "cmp");
您还可以使用any作为第二个参数。以下是一些例子:

  • 使用(来自PHP5.3)

  • 从班级内部

      usort($your_data, array($this, "cmp")); // "cmp" should be a method in the class
    
  • 使用(来自PHP7.4)


此外,如果您正在比较数值,
fn($a,$b)=>a->count-$b->count
作为“compare”函数应该可以实现这一点,或者,如果您想用另一种方法来做同样的事情,从PHP7开始,您可以使用,如下所示:
fn($a,$b)=>a->count count$b->count

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

请注意,PHP文档中没有这一点,但如果您使用的是5.3+闭包,并且可以提供可调用参数。

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

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

请记住,如果需要,请首先使用
LC\u 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);
  });

如果您正在使用此内部Codeigniter,则可以使用以下方法:

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

@谢谢你的建议。它确实帮助了我。

如果只需要按一个字段排序,那么
usort
是一个不错的选择。但是,如果需要按多个字段排序,解决方案很快就会变得混乱。在本例中,可以使用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'
函数($v){return$v->count;}
的简写形式(可以使用任意一种)。这些方法链返回迭代器,但如果需要,可以通过在最后添加
->toArray()
来获得数组


*由我开发的这里所有答案的缺点是它们使用静态字段名,所以我以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;
    }
} 
您可以从以下位置使用该功能:


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

usort($listable_products, function($a, $b) {
    global $translator;
    return strcmp($a->getFullTitle($translator), $b->getFullTitle($translator));
});
您可以使用此函数(适用于PHP版本>=5.3):


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

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

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

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

// Asc sort
usort($array,function($first,$second){
    return $first->number > $second->number;
});
//描述排序
usort($array,function($first,$second){
返回$first->number<$second->number;
});
//Asc排序
usort($array,function($first,$second){
返回$first->number>$second->number;
});
已更新 使用字符串时,不要忘记将其转换为相同的寄存器(上限或下限)

//描述排序
usort($array,function($first,$second){
返回strtolower($first->text)text);
});
//Asc排序
usort($array,function($first,$second){
返回strtolower($first->text)>strtolower($second->text);
});

如果一切都失败,这里有另一个解决方案:

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

如果你想对日期进行排序

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

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

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

这是基于的,它允许匿名函数。它是从PHP5.3开始提供的。

这是我对实用程序类的要求

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");
function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

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

usort($a, "cmp");
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");
你可以像这样使用usort

如果要按编号排序:

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

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

usort($a, "cmp");
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");

请参阅更多信息:

Demave到eating多键的参考答案

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

如果成功,
$result
将包含
TRUE
,您的比较应该是
$a->name>$b->name
:)@坎布拉卡:哦,忘了它通过引用接受数组。顺便说一句,OP没有说他需要按哪个顺序对集合进行排序。是的,这是一个数据库:)实际上来自一个函数,该函数从database@Alex:那你为什么不在数据库里排序呢<代码>按计数排序
更复杂,因为这是wordpress的标准功能部分,在我编写插件时,我无法更改wp文件。我使用create_函数尝试了您的示例(因为我在类中使用它,不知道如何将函数名传递给usort):
create_函数(“$a,$b”,“return$a->count<$b->count;”)
但我无法让它工作:(我收到一些通知和警告,usort希望参数2是一个有效的回调。我更喜欢这个参数,因为我们可以快速定义比较函数,并可以在类中使用。如果您想保留数组键,请使用
uasort()
进行排序描述,
-1*strcmp($a->name,$b->name);
无需乘法对desc进行排序。只需交换参数:
strcmp($b->name,$a->name)
您可能会遇到像我这样的情况,接受的答案比这个答案更可取。例如,您可能有一个父类和一个子类。子类重写使用
usort
的函数,但比较函数是相同的。使用此函数,您需要复制闭包的代码,而不是调用受保护的静态方法只需在父类中定义一次。这很好,但如果排序函数与调用函数在同一类中,则应使用:usort($your_data,array($This,“cmp”));@rmooney是的,但仅当您在类中时。如果您正在比较的模型/对象中有比较函数(我认为这是一种更干净的设计),请将
Util::sortArrayByName($array, "array_property_name");
function cmp($a, $b)
{
    if ($a == $b) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

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

usort($a, "cmp");
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");
 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;
}
$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'));