如何通过 asc 和 desc 的多个属性对 Laravel 集合进行排序?

Tar*_*dam 5 php sorting collections laravel

如果我有一个 Illuminate\Support\Collection,我如何使用 asc 和 desc 按多个属性排序?(这是一个简单的假设 - 根本不寻找有关查询构建的提示。)

$collection = User::all(); // not looking for User::orderBy()->get() solutions.  Read the question.
$sorting_insructions = [
    ['column'=>'first_name', 'order'=>'asc'],
    ['column'=>'date_of_birth', 'order'=>'desc'],
];
$collection->sort(function($a,$b) use ($sorting_instructions){
    // something...
});
Run Code Online (Sandbox Code Playgroud)

Air*_*Air 21

我知道这个问题是很久以前的问题,但以防万一有人偶然发现它,Laravel 现在确实提供了此功能(在撰写本文时为 v8.x)。

请参阅官方文档了解更多详细信息。(排序部分中的第四个代码块示例) https://laravel.com/docs/8.x/collections#method-sortby


来自文档:

如果您想按多个属性对集合进行排序,可以将排序操作数组传递给 sortBy 方法。每个排序操作应该是一个数组,其中包含您希望排序的属性和所需排序的方向:

$collection = collect([
    ['name' => 'Taylor Otwell', 'age' => 34],
    ['name' => 'Abigail Otwell', 'age' => 30],
    ['name' => 'Taylor Otwell', 'age' => 36],
    ['name' => 'Abigail Otwell', 'age' => 32],
]);

$sorted = $collection->sortBy([
    ['name', 'asc'],
    ['age', 'desc'],
]);

$sorted->values()->all();

/*
    [
        ['name' => 'Abigail Otwell', 'age' => 32],
        ['name' => 'Abigail Otwell', 'age' => 30],
        ['name' => 'Taylor Otwell', 'age' => 36],
        ['name' => 'Taylor Otwell', 'age' => 34],
    ]
*/
Run Code Online (Sandbox Code Playgroud)

应用于问题中的示例:

/*
$sorting_instructions = [
    ['column'=>'first_name', 'order'=>'asc'],
    ['column'=>'date_of_birth', 'order'=>'desc'],
];
*/

$collection = User::all(); 

$sortedCollection = $collection->sortBy([
    ['first_name','asc'],
    ['date_of_birth','desc'],
])

Run Code Online (Sandbox Code Playgroud)


Tar*_*dam 5

无论谁使用它,请记住 - 您需要根据您是否使用对象集合或关联数组来调整它。应该是一个简单的调整。只需将 $a[]/$b[] 内容更改为 $a-> 和 $b->

    public static function multiPropertySort(Collection $collection, array $sorting_instructions){

        return $collection->sort(function ($a, $b) use ($sorting_instructions){

            //stuff starts here to answer question...

            foreach($sorting_instructions as $sorting_instruction){

                $a[$sorting_instruction['column']] = (isset($a[$sorting_instruction['column']])) ? $a[$sorting_instruction['column']] : '';
                $b[$sorting_instruction['column']] = (isset($b[$sorting_instruction['column']])) ? $b[$sorting_instruction['column']] : '';

                if(empty($sorting_instruction['order']) or strtolower($sorting_instruction['order']) == 'asc'){
                    $x = ($a[$sorting_instruction['column']] <=> $b[$sorting_instruction['column']]);
                }else{
                    $x = ($b[$sorting_instruction['column']] <=> $a[$sorting_instruction['column']]);

                }

                if($x != 0){
                    return $x;
                }

            }

            return 0;

        })->values();
    }
Run Code Online (Sandbox Code Playgroud)