2017-01-18 259 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

$ cards有什麼價值? –

回答

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

它按顏色排序,但不按類型排序? – rotaercz

+0

您可以在之前和之後提供樣本數據集嗎? –

+0

我剛解決它,我張貼我的解決方案。儘管如果你的方法奏效了,它會非常甜蜜。 – rotaercz

0

這就是我解決它的方法。我知道它可以更好。

也許別人可以提供一個更優雅的解決方案,不需要更深入和更深的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; 
    }); 
} 
相關問題