1

Laravel 的Collection类 (v5.5) 有一种sortBy()方法可以对所有内容进行排序,类似于使用 SQLORDER BY语句,但有一个显着的区别:关系数据库在升序排序时会将NULL值放在末尾(或至少 PostgreSQL 会),但是 Laravel 的sortBy()方法将NULL值放在首位。

那么,在使用该方法时,如何让这些NULL值排在最后而不是排在最前面呢?请注意:我无法更改数据库查询本身!我唯一的选择是在 PHP 中对集合本身进行排序。在我的情况下,我绝对不能在数据库级别执行此操作。Collection::sortBy()

这里有一个关于 Stack Overflow 的类似问题,但是 OP 找到的解决方案有点像 hack,在我的情况下不起作用,因为我需要它来为 varchars 工作。

注意:我意识到sortBy()第一个参数接受一个闭包,但是文档中关于这个闭包接收的参数的解释为零$key(哪个“关键”是?),也没有明确说明闭包应该返回什么以确定排序顺序。(我假设它应该返回一个表示订单的整数,但我不知道如何使用多个NULL值使其对我有用。)

4

1 回答 1

1

sortBy方法接受一个按升序排序的字段。所以如果你有一个App\User对象的集合,你可以传入 say first_name,这将按每个用户的名字排序。

如果您的逻辑更复杂,并且您想对严格来说不是集合中每个项目的字段的内容进行排序,则可以改为传递闭包。传递给闭包的第一个参数是实际项目。您应该返回一个要从闭包中排序的值。假设在您的App\User对象集合中,您想按每个人名字的最后一个字母排序:

$users->sortBy(function ($item) {
    return substr($item->first_name, -1);
});

第二个参数是key,也就是集合的key,或者它所代表的底层数组。如果您从数据库中检索了一个集合,这可能是一个数字索引,但如果您有一个不同的集合,或者您决定通过用户的电子邮件地址 (Using keyBy) 重新键入集合,那么这就是已通过。

在将所有值粘贴null到排序结果集的末尾时,我建议使用该sort方法而不是sortBy. 当您将闭包传递给 时sort,它接受两个项目,代表您的集合中要排序的两个项目。对于您的App\User对象集合,每个项目都是App\User. 这使您可以完全控制两个对象的比较方式,从而完全控制顺序。

-1如果认为第一项小于第二项,则应返回(或负值),如果认为0两项相等,则应返回1(或正值),如果认为第一项大于比第二个。

$users->sort(function ($a, $b) {
    // Return -1, 0 or 1 here
});

这应该允许你实现你的逻辑。为确保null将值移至末尾,只需在1每次您感兴趣的时候返回 from $ais null。同样,如果您对 from $bis感兴趣,则null返回-1,如果您对两者感兴趣$a$bnull返回0

于 2018-01-17T21:13:43.813 回答