如何在 Laravel 5.1 中按多列对 Illuminate Collection 进行排序?
Posted
技术标签:
【中文标题】如何在 Laravel 5.1 中按多列对 Illuminate Collection 进行排序?【英文标题】:How to sort Illuminate Collection by multiple columns in Laravel 5.1? 【发布时间】:2016-02-16 06:05:07 【问题描述】:我有一个 Laravel 的 Illuminate Collection 实例。该数组包含多个属性。
我需要能够根据 2 个不同的属性对集合进行排序。
我想先按名为“sort”的属性排序,然后按名为“title”的属性排序。
此外,我还有另一个集合,如果 sort 的值不为 null,我喜欢按“sort”列对其进行排序,然后将“sort”值为 null 的项目打乱。
我怎样才能进行这种类型的排序?
【问题讨论】:
【参考方案1】:你可以给Collection::sort
提供回调函数:
$collection->sort(function($a, $b)
if($a->sort === $b->sort)
if($a->title === $b->title)
return 0;
return $a->title < $b->title ? -1 : 1;
return $a->sort < $b->sort ? -1 : 1;
);
这已记录在here。
【讨论】:
感谢您提供此代码。你能解释一下它是如何工作的吗? $b 和 $b 的值是多少?你为什么要返回 -1 或 1 ? 这里有很好的记录:secure.php.net/manual/en/… 非常感谢!很有帮助【参考方案2】:如果您使用的是 PHP 7,则可以使用 spaceship 运算符:
$collection->sort(function ($a, $b)
return $a->sort === $b->sort ? $a->title <=> $b->title : $a->sort <=> $b->sort;
);
<=>
符号称为宇宙飞船运算符(或技术上:组合比较运算符)。您可以在the RFC 阅读更多相关信息。
【讨论】:
【参考方案3】:其他答案(和 PHP 的文档)非常有帮助。经过一些实验,我发现你也可以对相关表进行排序。
在集合上使用->with($relatedTableName)
,然后按照所述使用->sort()
,您可以使用以下方法对相关表字段进行排序:
$baseTableField = "tableField"; // Field name from primary table/model $relatedTableMapString = "tableName.tableField"; // Field name from a related table $collection->with('relatedTableName')->sort(function($a, $b) use ($relatedTableMapString, $baseTableField) $relatedTableName = explode(".", $relatedTableMapString)[0]; $relatedTableFieldName = explode(".", $relatedTableMapString)[1]; if($a->$relatedTableName->$relatedTableFieldName === $b->$relatedTableName->$relatedTableFieldName) if($a->$baseTableField === $b->$baseTableField) return 0; return $a->$baseTableField < $b->$baseTableField ? -1 : 1; return $a->$relatedTableName->$relatedTableFieldName < $b->$relatedTableName->$relatedTableFieldName ? -1 : 1; );
【讨论】:
以上是关于如何在 Laravel 5.1 中按多列对 Illuminate Collection 进行排序?的主要内容,如果未能解决你的问题,请参考以下文章