2017-01-18 261 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; 
    }); 
} 
相关问题