2015-11-14 50 views
4

我有一个Laravel的Illuminate Collection的实例。该数组包含多个属性。如何在Laravel 5.1的多列中对Illuminate Collection进行排序?

我需要能够根据2个不同的属性对集合进行排序。

我想首先按名为“sort”的属性进行排序,然后按名为“title”的属性进行排序。

此外,我有另一个集合,我喜欢排序它的列“排序”,如果排序的值不为空,然后洗牌“排序”值为空的项目。

我该如何做这种类型的排序?

回答

8

您可以到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

+0

感谢您这段代码。你能解释它是如何工作的吗? $ b和$ b的值是多少?你为什么要返回-1或1? –

+0

这里有很好的文档:https://secure.php.net/manual/en/function.usort.php#refsect1-function.usort-parameters – svrnm

+0

非常感谢!非常有帮助 –

7

如果你使用PHP 7,您可以使用飞船操作:

$collection->sort(function ($a, $b) { 
    return $a->sort === $b->sort ? $a->title <=> $b->title : $a->sort <=> $b->sort; 
}); 

<=>符号被称为飞船操作人员(或技术:结合比较操作)。你可以在the RFC中阅读更多关于它的信息。

+0

1行代码尽一切:)谢谢! – Alex

0

其他答案(和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; 
});