如果我有一个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...
});
答案 0 :(得分:2)
无论是谁使用它,请记住 - 您需要根据您使用的对象集合或关联数组来调整它。应该是一个简单的调整。只需将$ 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();
}
答案 1 :(得分:1)
如果您使用Eloquent来获取集合实例,那么在查询中使用orderBy method会好得多,尤其是在列被编入索引时:
$sorting_insructions = [
['column'=>'first_name', 'order'=>'asc'],
['column'=>'date_of_birth', 'order'=>'desc'],
];
$collection = App\User::query();
foreach ($sorting_insructions as $value) {
$collection->orderBy($value['column'], $value['order']);
}
$users = $collection->get();
编辑由于编辑的问题告诉我应该在查询构建器之外使用排序,因此我认为$sorting_insructions
和sortBy的顺序与$collection = App\User::all();
$sorting_insructions = [
['column'=>'first_name', 'order'=>'asc'],
['column'=>'date_of_birth', 'order'=>'desc'],
];
for ($i = count($sorting_insructions) - 1; $i >= 0 ; $i--) {
extract($sorting_insructions[i]);
if ( $order === 'asc') {
$collection = $collection->sortBy( $column );
} else {
$collection = $collection->sortByDesc( $column );
}
}
的顺序相反给出了相同的结果:
revertFocus: function() {
var me = this,
focusEvent = me.focusEnterEvent,
activeElement = Ext.Element.getActiveElement(),
focusTarget, fromComponent, reverted;
// If we have a record of where focus arrived from,
// and have not been told to avoid refocusing,
// and we contain the activeElement.
// Then, before hiding, restore focus to what was focused before we were focused.
// --->>> THE IF BELOW: !me.preventRefocus <<<---
if (focusEvent && !me.preventRefocus && me.el.contains(activeElement)) {
答案 2 :(得分:0)
public static function multiPropertySort(
Collection $collection,
array $rules
)
{
return $collection->sort(
function ($a, $b) use ($rules) {
foreach($rules as $rule){
$sortColumn = array_get($rule, 'column');
array_set(
$a,
$sortColumn,
array_get($a, $sortColumn, '')
);
array_set(
$b,
$sortColumn,
array_get($b, $sortColumn, '')
);
if ($sortOrder = array_get($rule, 'order', 'asc')) {
$x = (array_get($a, $sortColumn) <=> array_get($b, $sortColumn));
} else {
$x = (array_get($b, $sortColumn) <=> array_get($a, $sortColumn));
}
if ($x != 0) {
return $x;
}
}
return 0;
}
);
}
让我们想象一下势在必行...
答案 3 :(得分:-1)
在问到这个问题之后,我不确定这是否是最好的方法(因为有许多循环),但这是非常简短的代码。
$sortDrives = $drives->groupBy('date')->sortBy('date');
$lastDrive = $sortDrives->map(function ($item, $key) {
return $item->sortBy('odometer');
})->collapse()->last();
我粘贴了我自己的例子,因为逻辑很简单,可以编辑它
<强>解释强>
让我们说: date1&lt; date2 和 odometer1&lt; odometer2&lt; odometer3 强>
首先你转过来:
[
0 => ['date' => date2, 'odometer' => odometer3],
1 => ['date' => date1, 'odometer' => odometer2],
2 => ['date' => date1, 'odometer' => odometer1],
]
分为:
[
date2 => [
0 => ['date' => date2, 'odometer' => odometer3]
],
date1 => [
0 => ['date' => date1, 'odometer' => odometer2],
1 => ['date' => date1, 'odometer' => odometer1]
]
]
然后用新密钥对其进行排序并获取:
[
date1 => ...
date2 => ...
]
之后,按键#2 排序,每个数组日期键指向:
[
date1 => [
0 => ['date' => date1, 'odometer' => odometer1],
1 => ['date' => date1, 'odometer' => odometer2]
]
date2 => [
0 => ['date' => date2, 'odometer' => odometer3]
],
]
最后你只是将所有这些数组碰撞在一起(删除日期键)并得到:
[
0 => ['date' => date1, 'odometer' => odometer1],
1 => ['date' => date1, 'odometer' => odometer2],
2 => ['date' => date2, 'odometer' => odometer3]
]