Laravel 的 Collection
类(v5.5)有一个 sortBy()
对所有内容进行排序的方法类似于使用 SQL ORDER BY
语句,但有一个显着的区别:关系数据库将 NULL
升序排序时末尾的值(或者至少 PostgreSQL 是这样),但 Laravel 的 sortBy()
方法 put NULL
值(value)观第一。
那么我如何获得这些NULL
使用Collection::sortBy()
时要最后而不是第一个排序的值方法? 请注意:我无法更改数据库查询本身!我唯一的选择是在 PHP 中对集合本身进行排序。在我的情况下,我绝对无法在数据库级别执行此操作。
有一个similar question on Stack Overflow here但 OP 找到的解决方案是一种 hack,在我的情况下不起作用,因为我需要它为 varchars 工作。
注意:我意识到sortBy()
接受第一个参数的闭包,但有 zero explanation in the documentation关于此闭包接收的参数(哪个“键”是 $key
?),也没有明确说明闭包应该返回什么以确定排序顺序。 (我假设它应该返回一个表示顺序的整数,但我不知道如何使用多个 NULL
值来实现它。)
最佳答案
sortBy
方法接受一个要按升序排序的字段。因此,如果您有 App\User
的集合对象,你可以传入 first_name
这将按每个用户的名字排序。
如果您的逻辑更复杂,并且您想要对集合中每个项目严格意义上不属于字段的内容进行排序,您可以传递一个闭包。传递给闭包的第一个参数是实际的项目。您应该返回一个要从闭包中排序的值。假设您收藏了 App\User
对象,您想按每个人名字的最后一个字母排序:
$users->sortBy(function ($item) {
return substr($item->first_name, -1);
});
第二个参数是key,是集合的key,或者说它代表的底层数组。如果您从数据库中检索了一个集合,这可能是一个数字索引,但如果您有一个不同的集合,或者您决定通过用户的电子邮件地址(使用 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
每次您感兴趣的内容都来自 $a
是 null
。同样,如果您对$b
中的任何内容感兴趣,是 null
,返回-1
如果您对 $a
感兴趣的话和$b
是null
,返回0
.
关于laravel - 如何使用 sortBy() 对 Laravel 集合进行升序排序,并将 NULL 值放在最后而不是第一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48309711/