【问题标题】:Sorting a Collection based on multiple criteria in Laravel在 Laravel 中根据多个条件对集合进行排序
【发布时间】:2017-06-03 07:34:40
【问题描述】:

我尝试先按颜色排序,然后按类型排序。

我在想也许双 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();
}

【问题讨论】:

  • $cards 有什么价值?

标签: php laravel sorting collections


【解决方案1】:

这里有一个宏可以为您做到这一点。将宏放在您的 app/Providers/AppServiceProvider.php'a 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();
}

【讨论】:

  • 是按颜色排序而不是按类型排序?
  • 能否给一个前后的样本数据集?
  • 我刚刚解决了它并发布了我的解决方案。不过,如果你的方法奏效了,那就太好了。
【解决方案2】:

我就是这样解决的。我知道它可以更好。

也许其他人可以提供一个更优雅的解决方案,不需要越来越深的 if 语句?

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;
    });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-11
    • 2014-06-25
    • 2020-10-27
    • 2023-02-01
    • 2019-02-21
    • 2020-07-05
    • 1970-01-01
    相关资源
    最近更新 更多