【问题标题】:Sorting laravel collection by leaving null/empty last通过将 null/empty 最后留空来对 laravel 集合进行排序
【发布时间】:2017-09-12 23:11:54
【问题描述】:

我似乎无法对 laravel 集合进行排序,所以 empty / null 数据最终会排在最后。 (对 usort 有点困惑)

我几乎只有一堆需要订购的times / timestamps。某些行可能没有该列。

我希望数据显示在ASC / ascendingempty/null 数据显示在最后。

$collection->sortBy('timestamp') 排序很好,但不知道如何处理空字段。

表格是这样的。

   $data = $data->sort(function($a, $b) use ($sortBy) {
        if ($a->{$sortBy} and $b->{$sortBy}) return 0; 
        return ($a->{$sortBy} > $b->{$sortBy}) ? -1 : 1;
    }); 

我从互联网上尝试的随机代码,我无法正常工作。 $sortBy 包含要排序的字段名称(因为它可能会更改) 错误的代码处理空/空数据,但它是无序的。

【问题讨论】:

  • 请添加您用于排序的代码。

标签: php laravel collections usort


【解决方案1】:

类似于Mr. Speelman's solution,但作为更短的 PHP 7.4+ 版本:

$collection->sortBy(fn($e) => $e->timestamp ?: PHP_INT_MAX)

【讨论】:

    【解决方案2】:

    我遇到了类似的问题。在我的例子中,$resulttime 属性可能是NULL。它就像NULL0 (就像int),这是预期的行为。但我也想通过最后留下NULL 对集合进行排序。

    $collection->sortBy(function ($result) {
        if ($result['time'] === NULL) {
            return PHP_INT_MAX;
        }
    
        return $result['time'];
    });
    

    您可以简单地通过返回一个比数组中所有其他值更高的值来实现此目的。即PHP_INT_MAX 以确保安全。这将确保time 等于NULL 的所有结果都位于数组的末尾。

    【讨论】:

      【解决方案3】:

      必须使用带有闭包的 sort()。下面将对时间戳 ASC 进行排序,最后为 NULL。

      $sorted = $collection->sort(function ($a, $b) {
          if (!$a->timestamp) {
              return !$b->timestamp ? 0 : 1;
          }
          if (!$b->timestamp) {
              return -1;
          }
          if ($a->timestamp == $b->timestamp) {
              return 0;
          }
      
          return $a->timestamp < $b->timestamp ? -1 : 1;
      });
      

      【讨论】:

        【解决方案4】:

        试试:

        $collection->sortBy('-timestamp')

        有效吗?

        【讨论】:

        • 这篇文章给了我灵感,这要归功于我认为我得到了它的工作。我没有使用 sortBy('-timestamp'),而是为每个条目创建了另一个变量,例如:我默认分配的 timestamp_order,随机数 -10000,如果有任何数据,该变量将被覆盖(时间戳不为空或空)。然后按 $collection->sortBy('timestamp_order') 排序
        • 我不喜欢这个主意,但很高兴它有效 :) 如果我的建议不起作用,也许尝试使用 CASE,如下例:ORDER BY (CASE WHEN timestamp IS NULL then 1 ELSE 0 END), timestamp 看看这里:stackoverflow.com/questions/5993109/…
        • 也不太喜欢这个想法,但由于我有很多关系 atm 和有限的时间框架来解决这个问题,所以我改为对集合进行排序。将随机数改为 Carbon::now()->addYear()->toDateTimeString();相反,由于它们比任何其他时间戳都早,所以它们出现在最后。
        【解决方案5】:

        我假设您的 timestamp 是 unix 时间戳。

        你可以这样排序:

        $sorted = $collection->sortByDesc('timestamp');
        

        【讨论】:

        • 这不是我想要实现的,我希望结果显示为 ASC / Ascending 而空 / null 数据是最后一个。
        猜你喜欢
        • 2015-01-26
        • 2021-01-15
        • 1970-01-01
        • 2013-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多