关于排序:Laravel-首先按字符串值对数组进行排序,然后对日期进行排序

Laravel - Sort array by string value first and then date

我需要帮助通过几个逻辑对数组进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[
  {
   "id": 1,
   "status":"pending",
   "date":"2019-08-01"
  },
  {
   "id": 2,
   "status":"delivered",
   "date":"2019-08-01"
  },
  {
   "id": 3,
   "status":"pending",
   "date":"2019-08-03"
  },
  {
   "id": 4,
   "status":"delivered",
   "date":"2019-08-03"
  },
  {
   "id": 5,
   "status":"delivered",
   "date":"2019-08-02"
  }
]

我要做的是先将数组排序为状态暂挂显示,然后按日期降序进行排序

我已经测试过使用laravel集合中的sortByDesc,但是该数组看起来只按1个函数进行了排序

1
2
3
4
5
6
7
$collection = $collection->sortByDesc('date')->sortByDesc(function ($row, $key) {
      if($row['status'] == 'pending'){
         return 1;
      }else{
         return 0;
      }
});

我预期的最终结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[
  {
   "id": 3,
   "status":"pending",
   "date":"2019-08-03"
  },
  {
   "id": 1,
   "status":"pending",
   "date":"2019-08-01"
  },
  {
   "id": 4,
   "status":"delivered",
   "date":"2019-08-03"
  },
  {
   "id": 5,
   "status":"delivered",
   "date":"2019-08-02"
  },
  {
   "id": 2,
   "status":"delivered",
   "date":"2019-08-01"
  }
]


很少有解决方案:

  • 使用自定义回调并返回数组源
  • 1
    2
    3
    $products->sortBy(function($product) {
                return [$product->param1, $product->param2];
     });

    This will sort a collection by param2 first, and then by param1

  • 使用自定义回调并返回一个复合属性以按源排序
  • 1
    2
    3
    $posts = $posts->sortBy(function($post) {
        return sprintf('%-12s%s', $post->column1, $post->column2);
    });
  • 按第1列对数组进行排序,然后按第2列对数组进行拆分,然后再次合并(未嵌套)。
  • 1
    2
    3
    $collection->sortByDesc('date');
    $collection->groupBy('status');
    $collection->keyBy('status');

    编辑:另外,我不确定sortByDesc('date')是否适用于日期字符串。


    更准确地说:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
          $collection= $collection->sort(
            function ($a, $b) {
                if(($a->status== $b->status) &&($a->status== 'pending')){
                    return ($a->date >= $b->date) ? -1 : 1;
                }elseif($a->status== 'pending' && ($a->status!= $b->status)){
                    return 1;
                }else{
                    return ($a->date <= $b->date) ? 1 : -1;
                }
            }
        );
        $collection= $collection->sortByDesc('status');

    您的预期结果可以这样实现。

    1
    2
    3
    4
    5
    6
    $sorted = $collection
                  ->sortByDesc('date')
                  ->sortBy(function ($item) {
                      return 'pending' == $item['status'] ? 0 : 1;
                  })
                  ->values();