Laravel Multiple Sortby не работает должным образом - PullRequest
0 голосов
/ 10 мая 2018

у меня есть некоторые проблемы с 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'
}]

Моя цель - отсортировать эти объекты в следующем порядке

оценка (asc)> int_premi (asc)> нормы (desc)> промо (как логическое значение) (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

Вместо, неследуя этому порядку ..

Так есть ли кто-нибудь, кто сталкивался с той же проблемой со мной?и, может быть, кто-то может помочь мне решить эту проблему?

Спасибо большое

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

После некоторых исследований .. я обнаружил, что один работает .. Если вы столкнулись с тем же самым, эта статья может помочь ..

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->sortByMulti([
    'prop_one'       => 'ASC',
    'prop_two'        => 'ASC',
    etc....
]);

prop_one и prop_two - это свойства вашей коллекции .. Надеюсь, что эта помощь

0 голосов
/ 10 мая 2018

Этот код отлично работает в соответствии с вашими потребностями. Но если вы хотите что-то изменить, вы можете прокомментировать:

$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;
...