Laravel的Collection
类(v5.5)有一个sortBy()
方法可以对所有类似的内容进行排序,如果您使用了SQL ORDER BY
语句,除非有一个引人注目差异:关系数据库会在排序升序时(或至少PostgreSQL确实)将NULL
值放在最后,但Laravel的sortBy()
方法会先放置NULL
值。
那么在使用NULL
方法时,如何将这些Collection::sortBy()
值排在最后而不是第一个? 请注意:我无法更改数据库查询本身!我唯一的选择是在PHP中对Collection本身进行排序。在我的情况下,我绝对不能在数据库级别这样做。
有一个similar question on Stack Overflow here但是OP找到的解决方案有点像黑客,并且在我的情况下不起作用,因为我需要它来为varchars工作。
注意:我意识到sortBy()
接受第一个参数的闭包,但关于此闭包接收的参数有zero explanation in the documentation("键"是$key
? ),也没有明确说出闭包应该返回什么以确定排序顺序。 (我假设它应该返回一个表示顺序的整数,但我不知道如何使用多个NULL
值为我工作。)
答案 0 :(得分:1)
sortBy
方法接受要按升序进行排序的字段。因此,如果您有一组App\User
个对象,则可以传入first_name
,并按每个用户的名字排序。
如果您的逻辑更复杂,并且您希望对集合中每个项目的字段进行严格排序,则可以通过闭包。传递给闭包的第一个参数是实际项。您应该返回一个要从闭包中排序的值。让我们在您的App\User
个对象集合中说,您希望按每个人的姓氏的最后一个字母排序:
$users->sortBy(function ($item) {
return substr($item->first_name, -1);
});
第二个参数是键,它是集合的键或它代表的底层数组。如果您从数据库中检索了一个集合,这可能是一个数字索引,但如果您有一个不同的集合,或者您决定重新键入该集合,请说明用户的电子邮件地址(使用keyBy
),那就是传递的内容。
如果要将所有null
值保留在排序结果集的末尾,我建议使用sort
方法而不是sortBy
。将闭包传递给sort
时,它会接受两个项目,表示要对您的集合中的两个项目进行排序。在收集App\User
个对象的情况下,每个项目都是App\User
的实例。这使您可以完全控制两个对象的比较方式,从而完全控制顺序。
如果第一项被认为小于第二项,则应返回-1
(或负值),如果要认为这两项是相等的,则应返回0
1
如果第一项被认为大于第二项,则为1}}(或正值)。
$users->sort(function ($a, $b) {
// Return -1, 0 or 1 here
});
这应该允许你实现你的逻辑。为确保将null
值移至最后,只要您对1
感兴趣的任何内容$a
,就返回null
。同样,如果您对$b
感兴趣的内容为null
,则返回-1
以及您对$a
和{{{{}}感兴趣的内容1}}是$b
,返回null
。