Laravel 多个排序方式无法正常工作
Laravel Multiple Sortby Not Working Properly
我对 laravel sortBy ( laravel 5.4 ) 有一些问题..根据我在许多网站上阅读的内容,它说进行多个 sortBy laravel 是通过使用反向订单..所以我尝试这样做..但仍然无法正常工作..
所以在这里..
我有这个对象集合...
[{
'product_id' => 468,
'name' => 'abc',
'int_premi' => 10000
'score' => 1000
'rates' => 0,
'views' => 0,
'promo' => null
},{
'product_id' => 472,
'name' => 'bcd',
'int_premi' => 10000
'score' => 1000
'rates' => 0,
'views' => 0,
'promo' => 'Some text here'
},{
'product_id' => 458,
'name' => 'def',
'int_premi' => 10000
'score' => 1000
'rates' => 0,
'views' => 0,
'promo' => 'ABC'
}]
我的目标是按照此顺序对这些对象进行排序
score ( asc ) > int_premi ( asc ) > rates ( desc ) > promo ( as
boolean ) ( desc ) > views ( desc ) > product_id ( desc )
所以我写了这段代码..
$collection->sortByDesc('product_id')->sortByDesc('views')->sortByDesc(function($arr,$k){
return !empty($arr->promo);
})->sortByDesc('rates')->sortBy('int_premi')->sortBy('score')->values()->all()
我正在寻找此订单附带的结果
BCD > DEF > ABC
相反,不遵循该顺序..
请问有没有人遇到和我一样的问题?也许有人可以帮助我解决这个问题?
非常感谢
根据您的需要,这段代码工作得很好。但是如果你想修改什么,你可以评论:
$collection = ([[
'product_id' => 468,
'name' => 'abc',
'int_premi' => 10000,
'score' => 1000,
'rates' => 0,
'views' => 0,
'promo' => null
],[
'product_id' => 472,
'name' => 'bcd',
'int_premi' => 10000,
'score' => 1000,
'rates' => 0,
'views' => 0,
'promo' => 'Some text here'
],[
'product_id' => 458,
'name' => 'def',
'int_premi' => 10000,
'score' => 1000,
'rates' => 0,
'views' => 0,
'promo' => 'ABC'
]]);
$collection = collect($collection)->sortByDesc('product_id')->sortByDesc('views')->sortByDesc('promo')->sortByDesc('rates')->sortBy('int_premi')->sortBy('score')->values()->all();
return $collection;
经过一些研究..我发现它正在工作..
如果你也遇到同样的事情..这篇文章可能会有所帮助..
https://www.jjanusch.com/2017/05/laravel-collection-macros-adding-a-sortbymuti-function
所以我的决赛与这篇文章的建议完全相同,通过创建一个宏..像这样
if (!Collection::hasMacro('sortByMulti')) {
/**
* An extension of the {@see Collection::sortBy()} method that allows for sorting against as many different
* keys. Uses a combination of {@see Collection::sortBy()} and {@see Collection::groupBy()} to achieve this.
*
* @param array $keys An associative array that uses the key to sort by (which accepts dot separated values,
* as {@see Collection::sortBy()} would) and the value is the order (either ASC or DESC)
*/
Collection::macro('sortByMulti', function (array $keys) {
$currentIndex = 0;
$keys = array_map(function ($key, $sort) {
return ['key' => $key, 'sort' => $sort];
}, array_keys($keys), $keys);
$sortBy = function (Collection $collection) use (&$currentIndex, $keys, &$sortBy) {
if ($currentIndex >= count($keys)) {
return $collection;
}
$key = $keys[$currentIndex]['key'];
$sort = $keys[$currentIndex]['sort'];
$sortFunc = $sort === 'DESC' ? 'sortByDesc' : 'sortBy';
$currentIndex++;
return $collection->$sortFunc($key)->groupBy($key)->map($sortBy)->ungroup();
};
return $sortBy($this);
});
}
然后你就可以像这样在你的 collection 上使用它
$collection->sortByMulti([
'prop_one' => 'ASC',
'prop_two' => 'ASC',
etc....
]);
prop_one 和 prop_two 是您的 collection 属性..
希望这有帮助
我对 laravel sortBy ( laravel 5.4 ) 有一些问题..根据我在许多网站上阅读的内容,它说进行多个 sortBy laravel 是通过使用反向订单..所以我尝试这样做..但仍然无法正常工作..
所以在这里.. 我有这个对象集合...
[{
'product_id' => 468,
'name' => 'abc',
'int_premi' => 10000
'score' => 1000
'rates' => 0,
'views' => 0,
'promo' => null
},{
'product_id' => 472,
'name' => 'bcd',
'int_premi' => 10000
'score' => 1000
'rates' => 0,
'views' => 0,
'promo' => 'Some text here'
},{
'product_id' => 458,
'name' => 'def',
'int_premi' => 10000
'score' => 1000
'rates' => 0,
'views' => 0,
'promo' => 'ABC'
}]
我的目标是按照此顺序对这些对象进行排序
score ( asc ) > int_premi ( asc ) > rates ( desc ) > promo ( as boolean ) ( desc ) > views ( desc ) > product_id ( desc )
所以我写了这段代码..
$collection->sortByDesc('product_id')->sortByDesc('views')->sortByDesc(function($arr,$k){
return !empty($arr->promo);
})->sortByDesc('rates')->sortBy('int_premi')->sortBy('score')->values()->all()
我正在寻找此订单附带的结果
BCD > DEF > ABC
相反,不遵循该顺序..
请问有没有人遇到和我一样的问题?也许有人可以帮助我解决这个问题?
非常感谢
根据您的需要,这段代码工作得很好。但是如果你想修改什么,你可以评论:
$collection = ([[
'product_id' => 468,
'name' => 'abc',
'int_premi' => 10000,
'score' => 1000,
'rates' => 0,
'views' => 0,
'promo' => null
],[
'product_id' => 472,
'name' => 'bcd',
'int_premi' => 10000,
'score' => 1000,
'rates' => 0,
'views' => 0,
'promo' => 'Some text here'
],[
'product_id' => 458,
'name' => 'def',
'int_premi' => 10000,
'score' => 1000,
'rates' => 0,
'views' => 0,
'promo' => 'ABC'
]]);
$collection = collect($collection)->sortByDesc('product_id')->sortByDesc('views')->sortByDesc('promo')->sortByDesc('rates')->sortBy('int_premi')->sortBy('score')->values()->all();
return $collection;
经过一些研究..我发现它正在工作.. 如果你也遇到同样的事情..这篇文章可能会有所帮助..
https://www.jjanusch.com/2017/05/laravel-collection-macros-adding-a-sortbymuti-function
所以我的决赛与这篇文章的建议完全相同,通过创建一个宏..像这样
if (!Collection::hasMacro('sortByMulti')) {
/**
* An extension of the {@see Collection::sortBy()} method that allows for sorting against as many different
* keys. Uses a combination of {@see Collection::sortBy()} and {@see Collection::groupBy()} to achieve this.
*
* @param array $keys An associative array that uses the key to sort by (which accepts dot separated values,
* as {@see Collection::sortBy()} would) and the value is the order (either ASC or DESC)
*/
Collection::macro('sortByMulti', function (array $keys) {
$currentIndex = 0;
$keys = array_map(function ($key, $sort) {
return ['key' => $key, 'sort' => $sort];
}, array_keys($keys), $keys);
$sortBy = function (Collection $collection) use (&$currentIndex, $keys, &$sortBy) {
if ($currentIndex >= count($keys)) {
return $collection;
}
$key = $keys[$currentIndex]['key'];
$sort = $keys[$currentIndex]['sort'];
$sortFunc = $sort === 'DESC' ? 'sortByDesc' : 'sortBy';
$currentIndex++;
return $collection->$sortFunc($key)->groupBy($key)->map($sortBy)->ungroup();
};
return $sortBy($this);
});
}
然后你就可以像这样在你的 collection 上使用它
$collection->sortByMulti([
'prop_one' => 'ASC',
'prop_two' => 'ASC',
etc....
]);
prop_one 和 prop_two 是您的 collection 属性.. 希望这有帮助