我如何排序这个对象数组的一个字段,如名称或计数?

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
        )

   ....

当前回答

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

其他回答

如果你正在使用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')); 

如果您只需要根据一个字段进行排序,那么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'是函数($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;
    }
} 

要对一列值进行排序,array_column()和array_multisort()的组合是一种合理的方法。演示

array_multisort(array_column($array, 'count'), $array);

或者在这种情况下,只使用太空船操作符调用usort()以减少迭代。演示

usort($array, fn($a, $b) => $a->count <=> $b->count);

注意,尽管计数值被转换为输入数组中的字符串类型值,但这两个排序函数都将正确地按数字排序,而不是按字母顺序排序(错误地将23420放在420之前)。这是一个可靠的默认特性。

即使变量声明要排序的列,这两种方法都允许使用变量,而不需要任何添加技术。

带变量的多排序演示

$property = 'count';
array_multisort(array_column($array, $property), $array);

使用变量Usort演示

$property = 'count';
usort($array, fn($a, $b) => $a->$property <=> $b->$property);

这两个原生排序函数都是通过引用修改的,所以不要尝试通过它们的返回值访问已排序的数组。

array_multisort()的默认排序方向是升序的,因此在两个数组参数之间显式使用SORT_ASC没有任何好处。如果需要降序排序,则在两个数组之间写入SORT_DESC(作为第二个参数)。

当自定义函数体将$a数据放在宇宙飞船操作符的左侧,$b数据放在右侧时,Usort()将升序排序。对于降序排序,只需将$b的数据写在左边,$a的数据写在右边。

这两种方法都能够接收多个排序规则,但是由于这个问题只要求对单个列进行排序,因此在这里不适合使用该指导。

在排序时每次迭代都调用函数(如strcmp())效率较低。这不再是最佳实践。使用双向比较(如>或<)来返回布尔结果也不是这样。usort()期望进行三向比较。

对于有多个规则/列/属性的数据排序,这个答案提供了很好的指导。

usort($array, 'my_sort_function');

var_dump($array);

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

同样的代码将用于计数字段。

更多关于usort的详细信息:http://ru2.php.net/usort

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