我正在尝试先按颜色排序然后按类型排序。
我想也许双重foreach循环可能不是答案?
以下是我到目前为止的情况。
private $color_order = [
'white',
'green',
'purple',
'blue',
''
];
private $type_order = [
'diamond',
'square',
'circle'
];
private function sortCards($cards, $color_order, $type_order) {
$collection = collect($cards);
return $collection->sortBy(function($card) use ($color_order, $type_order) {
foreach ($type_order as $index => $type) {
foreach ($color_order as $index => $color) {
if ($card->card_colors == $color && str_contains($card->card_type, $type)) {
return $index;
}
}
}
})->values();
}
答案 0 :(得分:0)
这是一个可以为您完成此操作的宏。将宏放在app/Providers/AppServiceProvider.php
'boot()
方法中:
use Illuminate\Support\Collection;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Collection::macro('sortByMany', function($params) {
return $this->sortBy(function($item) use ($params) {
$sort = '';
foreach($params as $property => $sortOrder) {
$key = array_search($item->{$property}, $sortOrder);
$sort .= $key === false ? count($sortOrder) + 1 : $key;
}
return (int) $sort;
});
});
}
}
然后,您可以使用排序顺序数组['objectProperty' => ['sortorder'], 'otherProp' => ['otherSortOrder']]
来调用它。它将按照传递给方法的顺序对属性进行排序。在您的示例中,它将是:
private function sortCards($cards, $color_order, $type_order)
{
return collect($cards)->sortByMany(['card_colors' => $color_order, 'card_type' => $type_order])->values();
}
答案 1 :(得分:0)
这就是我解决它的方式。我知道它会更好。
也许其他人可以提供更优雅的解决方案,如果声明不会更深入,更深入?
private function sortCards($cards, $color_order, $type_order) {
return $cards->sort(function($a, $b) use ($color_order, $type_order) {
$pos_a = array_search($a->card_colors, $color_order);
$pos_b = array_search($b->card_colors, $color_order);
if ($pos_a == $pos_b) {
$pos_a = array_search($a->card_types, $type_order);
$pos_b = array_search($b->card_types, $type_order);
if ($pos_a == $pos_b) return 0;
return $pos_a - $pos_b;
}
return $pos_a - $pos_b;
});
}