2017-11-15 6 views
1

Illuminate \ Support \ Collectionがある場合、ascとdescの両方で複数のプロパティを並べ替えるにはどうすればよいですか? (これは、単純な仮定で - 。全くクエリの構築のヒントを探していません)Laravel Collectionをascとdescの両方で複数のプロパティで並べ替えるにはどうすればよいですか?

$collection = User::all(); // not looking for User::orderBy()->get() solutions. Read the question. 
$sorting_insructions = [ 
    ['column'=>'first_name', 'order'=>'asc'], 
    ['column'=>'date_of_birth', 'order'=>'desc'], 
]; 
$collection->sort(function($a,$b) use ($sorting_instructions){ 
    // something... 
}); 

答えて

1

これを使用しています誰が、ちょうど心に留めておく - あなたはあなたの使用してオブジェクトのコレクションまたは連想場合によっては、それを微調整する必要がありますアレイ。簡単に調整する必要があります。ちょうどあなたがあなたのコレクションのインスタンスを取得するために雄弁を使用している場合、でorderBy methodを使用するより良いだろう$ A-に[]のもの$ []/$ bを変更する>と$ B->

public static function multiPropertySort(Collection $collection, array $sorting_instructions){ 

     return $collection->sort(function ($a, $b) use ($sorting_instructions){ 

      //stuff starts here to answer question... 

      foreach($sorting_instructions as $sorting_instruction){ 

       $a[$sorting_instruction['column']] = (isset($a[$sorting_instruction['column']])) ? $a[$sorting_instruction['column']] : ''; 
       $b[$sorting_instruction['column']] = (isset($b[$sorting_instruction['column']])) ? $b[$sorting_instruction['column']] : ''; 

       if(empty($sorting_instruction['order']) or strtolower($sorting_instruction['order']) == 'asc'){ 
        $x = ($a[$sorting_instruction['column']] <=> $b[$sorting_instruction['column']]); 
       }else{ 
        $x = ($b[$sorting_instruction['column']] <=> $a[$sorting_instruction['column']]); 

       } 

       if($x != 0){ 
        return $x; 
       } 

      } 

      return 0; 

     }); 
    } 
+0

...さんは不可欠なものを想像してみましょうか?たぶん 'array' – Piterden

+0

また、Laravelの安全なarray_get array_set – Piterden

+0

@Piterdenを使用する方が良いでしょう - あなたの編集でそこにジャンプしてください! –

1

カラムがインデックスされた場合は特に、あなたのクエリ、:

$sorting_insructions = [ 
    ['column'=>'first_name', 'order'=>'asc'], 
    ['column'=>'date_of_birth', 'order'=>'desc'], 
]; 

$collection = App\User::query(); 

foreach ($sorting_insructions as $value) { 

    $collection->orderBy($value['column'], $value['order']); 

} 

$users = $collection->get(); 

をEDIT質問はその種を語って編集されたので、クエリビルダ外で使用しなければならない、私は$sorting_insructionsから逆の順序でsortBysortByDescを連鎖すると同じ結果が得られると思います:

$collection = App\User::all(); 

$sorting_insructions = [ 
    ['column'=>'first_name', 'order'=>'asc'], 
    ['column'=>'date_of_birth', 'order'=>'desc'], 
]; 

for ($i = count($sorting_insructions) - 1; $i >= 0 ; $i--) { 

    extract($sorting_insructions[i]); 

    if ($order === 'asc') { 
     $collection = $collection->sortBy($column); 
    } else { 
     $collection = $collection->sortByDesc($column); 
    } 

} 
+2

それは完全に質問のポイントを逃す。 –

+1

これは返されたデータを注文するためのmysqlジョブだと思っています。もし私がEloquentがすでに私に提供しているのであれば、あなたのソリューションを使うのですか? – YouneL

+0

質問のフレーミングは単純な仮説に過ぎないので、コレクションのソートが必要です。 –

0
public static function multiPropertySort(
    Collection $collection, 
    array $rules 
) 
{ 
    return $collection->sort(
     function ($a, $b) use ($rules) { 
      foreach($rules as $rule){ 
       $sortColumn = array_get($rule, 'column'); 

       array_set(
        $a, 
        $sortColumn, 
        array_get($a, $sortColumn, '') 
       ); 

       array_set(
        $b, 
        $sortColumn, 
        array_get($b, $sortColumn, '') 
       ); 

       if ($sortOrder = array_get($rule, 'order', 'asc')) { 
        $x = (array_get($a, $sortColumn) <=> array_get($b, $sortColumn)); 
       } else { 
        $x = (array_get($b, $sortColumn) <=> array_get($a, $sortColumn)); 
       } 

       if ($x != 0) { 
        return $x; 
       } 
      } 

      return 0; 
     } 
    ); 
} 

`Array`

関連する問題