如何在 Laravel 5.1 中按多列对 Illuminate Collection 进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33713392/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 12:41:35  来源:igfitidea点击:

How to sort Illuminate Collection by multiple columns in Laravel 5.1?

phparrayssortinglaravel

提问by Junior

I have a an instance of Laravel's Illuminate Collection. The array contains multiple properties.

我有一个 Laravel 的 Illuminate Collection 实例。该数组包含多个属性。

I need to be able to sort the collection based on 2 different attributes.

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

I want to first sort by the attribute that is called "sort" and then by an attribute called "title".

我想首先按称为“排序”的属性排序,然后按称为“标题”的属性排序。

Additionally, I have another collection that I like to sort it by the column "sort" if the value of sort is not null, then shuffle the items that have null for "sort" value.

此外,我还有另一个集合,如果 sort 的值不为 null,我喜欢按“sort”列对其进行排序,然后将“sort”值的 null 项打乱。

How can I do this type of sort?

我怎样才能做这种类型的排序?

回答by svrnm

You can provide a callback function to Collection::sort:

您可以向以下对象提供回调函数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;
});

This is documented here.

在此处记录

回答by Joseph Silber

If you're using PHP 7, you can use the spaceship operator:

如果您使用的是 PHP 7,则可以使用 spaceship 运算符:

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

The <=>symbol is called the spaceship operator (or technically: the combined comparison operator). You can read more about it in the RFC.

<=>符号称为飞船运算符(或技术上:组合比较运算符)。您可以在RFC 中阅读有关它的更多信息。

回答by Keith DC

The other answers (and PHP's documentation) were very helpful. After some experimenting, I found you can also sort on related tables as well.

其他答案(和 PHP 的文档)非常有帮助。经过一些试验,我发现您也可以对相关表进行排序。

Using the ->with($relatedTableName)on the collection, and then using the ->sort()as described, you can sort on a related table field by using:

使用->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;
});
$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;
});