2017-01-18 5 views
0

Я пытаюсь сортировать по цвету сначала, а затем сортировать по типу.Сортировка коллекции по нескольким критериям в Laravel

Я думаю, что, возможно, двойные петли 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.phpboot():

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(); 
} 
+0

Сортировка по цвету, но не по типу? – rotaercz

+0

Можете ли вы предоставить образец данных до и после? –

+0

Я просто решил это, и я отправил свое решение. Хотя, если бы ваш метод работал, это было бы довольно мило. – rotaercz

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; 
    }); 
} 
Смежные вопросы