April 22, 2018 —John Koster
The sortBy
method is useful and versatile way to sort collections by some key, or by some value returned by a $callback
. The $callback
can either be a function that defines two parameters: $value
and $key
or the $callback
can be the name of some key to sort the collection by. The $options
parameter allows developers to modify the sorting behavior and the $descending
parameter controls whether or not the sortBy
method will sort the collection ascending (false
) or descending (true
). The sortBy
method does not modify the original collection instance, but will return a new instance of Collection
with the items sorted.
1public function sortBy(2 $callback,3 $options = SORT_REGULAR,4 $descending = false5);
The following collection of imaginary users will be used when demonstrating the features of the sortBy
method:
1use Illuminate\Support\Collection; 2 3// Create a new collection instance. 4$collection = new Collection([ 5 [ 6 'name' => 'Sue', 7 'age' => 23, 8 'followers' => [ 9 'Jim',10 'Donna'11 ]12 ],13 [14 'name' => 'Simon',15 'age' => 38,16 'followers' => [17 'Sue'18 ]19 ],20 [21 'name' => 'Jane',22 'age' => 25,23 'followers' => [24 'Link',25 'Dave',26 'Chase'27 ]28 ],29 [30 'name' => 'Dave',31 'age' => 19,32 'followers' => [33 'Dee Dee',34 'Stevie'35 ]36 ]37]);
It is possible to sort the $collection
by name
like so:
1// Sort the users by name:2$sorted = $collection->sortBy('name');
The $sorted
variable would now be an instance of Collection
and the items would be in the following order:
1Dave2Jane3Simon4Sue
To reverse the order, the following could be used:
1$sorted = $collection->sort('name', SORT_REGULAR, true);
The $sorted
collection would now be in the following order:
1Sue2Simon3Jane4Dave
The users can also be sorted by the number of followers they have. To accomplish this, a callback function must be used:
1// Sort the users by the number of followers.2$sorted = $collection->sortBy(function($value, $key) {3 return count($value['followers']);4});
The $sorted
collection would now be in the following order:
1Simon2Sue3Dave4Jane
Of course, it is often desirable to see which users have the most followers. To do this, use the same techniques as before to change the sort order to descending:
1// Sort the users by the number of followers.2$sorted = $collection->sortBy(function($value, $key) {3 return count($value['followers']);4}, SORT_REGULAR, true);
sortBy
OptionsThe $options
parameter allows developers to change the sorting behavior of the sortBy
method. The accepted options are the same options that are defined for PHP's sort
function. The following collection instance will be used throughout this section when describing the behavior of the various options:
1use Illuminate\Support\Collection; 2 3 4/** 5 * A simple class to represent an animal. 6 * 7 * Its only purpose to accept the name of the 8 * animal and return it when the object 9 * instance is cast to a string.10 */11class Animal {12 13 /**14 * The name of the animal.15 *16 * @var string17 */18 private $name = '';19 20 public function __construct($name) {21 $this->name = $name;22 }23 24 public function __toString() {25 return $this->name;26 }27 28}29 30// Create a new collection instance.31$collection = new Collection([32 0 => 'a2.txt',33 1 => 'a1.txt',34 2 => 'a4.txt',35 3 => new Animal('KANGAROO'),36 4 => new Animal('kangaroo'),37 5 => 'a3.txt',38 6 => 6,39 7 => 5,40 8 => new Animal('macaw'),41 9 => 'candice',42 10 => 'bob',43 11 => 'alice',44 12 => new Animal('zebra')45]);
The $collection
contains a diverse range of items. It contains strings, integers and a few Animal
instances. The keys of each item have also been explicitly set. This will make it easier to keep track of where each item has moved after the collection is sorted.
The following sort flags are available when using the sortBy
method:
Flag | Description |
---|---|
SORT_REGULAR |
This is the default sorting flag. It compares each item normally, without changing the type of each item when comparing. |
SORT_NUMERIC |
This flag will cause each item to be treated as a number when doing the comparison. |
SORT_STRING |
This flag will cause each item to be treated as a string when doing the comparison. |
SORT_LOCALE_STRING |
This flag will cause each item to be treated as a string when doing the comparison, but will also take into account PHP's current locale. |
SORT_NATURAL |
This flag compares each item a string, using a "natural ordering" sorting algorithm, similar to the sort method when working with collections. |
SORT_FLAG_CASE |
Can be combined with the SORT_STRING and SORT_NATURAL flags to sort the strings in a case-insensitive way. |
The following tables will show how the different sorting flags change the sorting of the previously made $collection
. Each sorting flag has its own section, which will follow this section. The first table shows the key and its associated value from the original collection, which can be used to locate the original item from the table that follows. The table that follows shows each sorting flag and the sorting order that would result from using that sorting flag. The collection was sorted by using the string representation of the item's value.
Collection Keys and Values:
Key | Data Type | Value |
---|---|---|
0 |
string | a2.txt |
1 |
string | a1.txt |
2 |
string | a4.txt |
3 |
object | (Animal) KANGAROO |
4 |
object | (Animal) kangaroo |
5 |
string | a3.txt |
6 |
integer | 6 |
7 |
integer | 5 |
8 |
object | (Animal) macaw |
9 |
string | candice |
10 |
string | bob |
11 |
string | alice |
12 |
object | (Animal) zebra |
Sorting Flag Result Comparison:
| Original Order | 0 1 2 3 4 5 6 7 8 9 10 11 12
|
| SORT_REGULAR | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_NUMERIC | 8 9 10 11 0 5 2 1 3 4 12 7 6
|
| SORT_STRING | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_STRING | SORT_FLAG_CASE | 7 6 1 0 5 2 11 10 9 4 3 8 12
|
| SORT_LOCALE_STRING | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_NATURAL | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_NATURAL | SORT_FLAG_CASE | 7 6 1 0 5 2 11 10 9 4 3 8 12
|
SORT_NUMERIC
FlagThe SORT_NUMERIC
treats each item as a number when doing the comparison. The following code example shows how to use the SORT_NUMERIC
flag when sorting the $collection
created previously (the callback function will return the string representation of the item):
1// Sort the collection using the SORT_NUMERIC flag.2$sorted = $collection->sortBy(function($value, $key) {3 return (string) $value;4}, SORT_NUMERIC);
The following table will use each item's key to represent the new sort order. It will compare the original collection order, the order when using the SORT_REGULAR
flag and the order when using the SORT_NUMERIC
flag.
SORT_NUMERIC Result Comparison:
|---|---|
| Original Order | 0 1 2 3 4 5 6 7 8 9 10 11 12
|
| SORT_REGULAR | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_NUMERIC | 8 9 10 11 0 5 2 1 3 4 12 7 6
|
SORT_STRING
FlagThe SORT_STRING
treats each item as a string when doing the comparison. The following code example shows how to use the SORT_STRING
flag when sorting the $collection
created previously (the callback function will return the string representation of the item):
1// Sort the collection using the SORT_STRING flag.2$sorted = $collection->sortBy(function($value, $key) {3 return (string) $value;4}, SORT_STRING);
The following table will use each item's key to represent the new sort order. It will compare the original collection order, the order when using the SORT_REGULAR
flag and the order when using the SORT_STRING
flag.
SORT_STRING Result Comparison:
|---|---|
| Original Order | 0 1 2 3 4 5 6 7 8 9 10 11 12
|
| SORT_REGULAR | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_STRING | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
SORT_STRING
and SORT_FLAG_CASE
Flags for Case InsensitivityThe SORT_FLAG_CASE
flag can be combined with the SORT_STRING
flag to treat each item as a string while also ignored the case of each item. The following example shows how to use the SORT_STRING
with the SORT_FLAG_CASE
flag when sorting the $collection
created previously (the callback function will return the string representation of the item):
1// Sort the collection using the SORT_STRING and the2// SORT_FLAG_CASE flags.3$sorted = $collection->sortBy(function($value, $key) {4 return (string) $value;5}, SORT_STRING | SORT_FLAG_CASE);
The following table will use each item's key to represent the new sort order. It will compare the original collection order, the order when using the SORT_STRING
flag and the order when using the SORT_STRING
combined with the SORT_FLAG_CASE
flag.
SORT_STRING | SORT_FLAG_CASE Result Comparison:
|---|---|
| Original Order | 0 1 2 3 4 5 6 7 8 9 10 11 12
|
| SORT_STRING | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_STRING | SORT_FLAG_CASE | 7 6 1 0 5 2 11 10 9 4 3 8 12
|
SORT_LOCALE_STRING
FlagThe SORT_LOCALE_STRING
treats each item as a string, while also taking into account the current locale, when doing the comparison. The following code example shows how to use the SORT_LOCALE_STRING
flag when sorting the $collection
created previously (the callback function will return the string representation of the item):
1// Sort the collection using the SORT_LOCALE_STRING flag.2$sorted = $collection->sortBy(function($value, $key) {3 return (string) $value;4}, SORT_LOCALE_STRING);
The following table will use each item's key to represent the new sort order. It will compare the original collection order, the order when using the SORT_REGULAR
flag and the order when using the SORT_LOCALE_STRING
flag.
SORT_LOCALE_STRING Result Comparison:
|---|---|
| Original Order | 0 1 2 3 4 5 6 7 8 9 10 11 12
|
| SORT_REGULAR | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_LOCALE_STRING | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
SORT_NATURAL
FlagThe SORT_NATURAL
treats each item as a string while using a "natural ordering" algorithm to perform the sorting. The following code example shows how to use the SORT_NATURAL
flag when sorting the $collection
created previously (the callback function will return the string representation of the item):
1// Sort the collection using the SORT_NATURAL flag.2$sorted = $collection->sortBy(function($value, $key) {3 return (string) $value;4}, SORT_NATURAL);
The following table will use each item's key to represent the new sort order. It will compare the original collection order, the order when using the SORT_REGULAR
flag and the order when using the SORT_NATURAL
flag.
SORT_NATURAL Result Comparison:
|---|---|
| Original Order | 0 1 2 3 4 5 6 7 8 9 10 11 12
|
| SORT_REGULAR | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_NATURAL | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
SORT_NATURAL
and SORT_FLAG_CASE
Flags for Case InsensitivityThe SORT_FLAG_CASE
flag can be combined with the SORT_NATURAL
flag to treat each item as a string while also ignored the case of each item. The following example shows how to use the SORT_NATURAL
with the SORT_FLAG_CASE
flag when sorting the $collection
created previously (the callback function will return the string representation of the item):
1// Sort the collection using the SORT_NATURAL and the2// SORT_FLAG_CASE flags.3$sorted = $collection->sortBy(function($value, $key) {4 return (string) $value;5}, SORT_NATURAL | SORT_FLAG_CASE);
The following table will use each item's key to represent the new sort order. It will compare the original collection order, the order when using the SORT_NATURAL
flag and the order when using the SORT_NATURAL
combined with the SORT_FLAG_CASE
flag.
SORT_NATURAL | SORT_FLAG_CASE Result Comparison:
|---|---|
| Original Order | 0 1 2 3 4 5 6 7 8 9 10 11 12
|
| SORT_NATURAL | 7 6 3 1 0 5 2 11 10 9 4 8 12
|
| SORT_NATURAL | SORT_FLAG_CASE | 7 6 1 0 5 2 11 10 9 4 3 8 12
|
sortBy
With Higher Order MessagesIn the following example, we will use the sortBy
with higher order messages, which allows us to invoke certain collection methods using PHP's property accessors syntax. To start, we will create a new PeripheralDevice
class which will simply hold the name of various peripheral devices:
The PeripheralDevice
Class:
1class PeripheralDevice2{3 public $name = '';4 5 public function __construct($name)6 {7 $this->name = $name;8 }9}
Using the new PeripheralDevice
class, we can create a collection of device names, transform the simple names into objects, and then sort by the device's name using higher order messages:
1$devices = collect([2 'monitor',3 'keyboard',4 'printer',5 'mouse',6 'microphone'7 ])->transform(function ($device) {8 return new PeripheralDevice($device);9 })->sortBy->name;
After the above code has executed, the $devices
variable would reference a collection instance containing PeripheralDevice
objects that are sorted alphabetically.
∎
The following amazing people help support this site and my open source projects ♥️
If you're interesting in supporting my work and want to show up on this list, check out my GitHub Sponsors Profile.