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

これはあなたのために行うマクロです。

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']]としてソート順の配列とそれを呼び出すことができます。あなたのapp/Providers/AppServiceProvider.phpboot()方法でマクロを置きます。メソッドに渡された順序でプロパティがソートされます。あなたの例では:

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; 
    }); 
} 
関連する問題