Laravel 5 Collections: Grouping Collection Elements With groupBy / Blog / Stillat
The groupBy
method is used to group a collection based on a given value, represented by the $groupBy
parameter. An argument passed to $groupBy
can be a simple string, representing the value that the collection should be grouped by, or a callback that returns the value the collection should be grouped by. By default, the groupBy
method does not preserve the keys of the collection when grouping, but that can be changed by passing true
as the argument to the $preserveKeys
parameter. The groupBy
returns a new instance of the Collection
class.
1
public
function
groupBy
(
2
$groupBy,
3
$preserveKeys
=
false
4
);
#Example Use
The following collection will be used throughout this section when demonstrating the groupBy
method:
1
use
Illuminate\Support\Collection
;
2
3
// Create a new collection instance.
4
$collection
=
new
Collection
([
5
[
6
'genus'
=>
'Canis'
,
7
'species'
=>
'C. lupus'
,
8
'subspecies'
=>
'C. l. albus'
,
9
'name'
=>
'tundra wolf'
10
],
11
[
12
'genus'
=>
'Canis'
,
13
'species'
=>
'C. lupus'
,
14
'subspecies'
=>
'C. l. arctos'
,
15
'name'
=>
'arctic wolf'
16
],
17
[
18
'genus'
=>
'Cucumis'
,
19
'species'
=>
'C. sativus'
,
20
'subspecies'
=>
null
,
21
'name'
=>
'cucumber'
22
]
23
]);
The collection be grouped by the genus of each item like so:
1
$genera
=
$collection
->
groupBy
(
'genus'
);
The $genera
variable will now be an instance of Collection
, and will contain numerous items, each an instance of Collection
. The above $genera
variable will now have a value similar to the following output:
1
object(Illuminate\Support\Collection)
2
protected 'items' =>
3
array
4
'Canis' =>
5
object(Illuminate\Support\Collection)
6
protected 'items' =>
7
array
8
0 =>
9
array
10
'genus' => string 'Canis'
11
'species' => string 'C. lupus'
12
'subspecies' => string 'C. l. albus'
13
'name' => string 'tundra wolf'
14
1 =>
15
array (size=4)
16
'genus' => string 'Canis'
17
'species' => string 'C. lupus'
18
'subspecies' => string 'C. l. arctos'
19
'name' => string 'arctic wolf'
20
'Cucumis' =>
21
object(Illuminate\Support\Collection)
22
protected 'items' =>
23
array
24
0 =>
25
array
26
'genus' => string 'Cucumis'
27
'species' => string 'C. sativus'
28
'subspecies' => null
29
'name' => string 'cucumber'
The original collection was split into two new collections: Cucumis
and Canis
. Each item that was grouped into the Canis
collection can be retrieve like so:
1
$canisGenus
=
$genera
->
get
(
'Canis'
):
The $canisGenus
variable would now contain a value similar to the following output:
1
object(Illuminate\Support\Collection)
2
protected 'items' =>
3
array
4
0 =>
5
array
6
'genus' => string 'Canis'
7
'species' => string 'C. lupus'
8
'subspecies' => string 'C. l. albus'
9
'name' => string 'tundra wolf'
10
1 =>
11
array
12
'genus' => string 'Canis'
13
'species' => string 'C. lupus'
14
'subspecies' => string 'C. l. arctos'
15
'name' => string 'arctic wolf'
A callback can also be supplied for the $groupBy
parameter. The callback should accept an $item
and a $key
argument, and should also return the criteria that the collection should be grouped by. The following code example will group the original collection based on the length of each items name
:
1
$groupedByNameLength
=
$collection
->
groupBy
(
2
function
($item, $key) {
3
return
strlen
($item[
'name'
]);
4
}
5
);
The $groupedByNameLength
variable would be an instance of Collection
and contain a value similar to the following output:
1
object(Illuminate\Support\Collection)
2
protected 'items' =>
3
array
4
11 =>
5
object(Illuminate\Support\Collection)
6
protected 'items' =>
7
array
8
0 =>
9
array
10
'genus' => string 'Canis'
11
'species' => string 'C. lupus'
12
'subspecies' => string 'C. l. albus'
13
'name' => string 'tundra wolf'
14
1 =>
15
array
16
'genus' => string 'Canis'
17
'species' => string 'C. lupus'
18
'subspecies' => string 'C. l. arctos'
19
'name' => string 'arctic wolf'
20
8 =>
21
object(Illuminate\Support\Collection)
22
protected 'items' =>
23
array
24
0 =>
25
array
26
'genus' => string 'Cucumis'
27
'species' => string 'C. sativus'
28
'subspecies' => null
29
'name' => string 'cucumber'
#Preserving Keys With groupBy
By default, the groupBy
method will not preserve the keys in the underlying collection when grouping items. The following code sample shows how the groupBy
method groups by default, and the output:
1
use
Illuminate\Support\Collection
;
2
3
4
// Create a new collection instance.
5
$collection
=
new
Collection
([
6
'first'
=>
[
'name'
=>
'Dave'
,
'age'
=>
30
],
7
'second'
=>
[
'name'
=>
'Jim'
,
'age'
=>
30
],
8
'third'
=>
[
'name'
=>
'Sarah'
,
'age'
=>
27
]
9
]);
10
11
$grouped
=
$collection
->
groupBy
(
'age'
);
The $grouped
variable would now have a value similar to the following output:
1
object(Illuminate\Support\Collection)
2
items' =>
3
array
4
30 =>
5
object(Illuminate\Support\Collection)
6
protected 'items' =>
7
array
8
0 =>
9
^== Notice that the keys were
10
NOT preserved.
11
array
12
'name' => string 'Dave'
13
'age' => int 30
14
1 =>
15
^== Notice that the keys were
16
NOT preserved.
17
array
18
'name' => string 'Jim'
19
'age' => int 30
20
27 =>
21
object(Illuminate\Support\Collection)
22
protected 'items' =>
23
array
24
0 =>
25
^== Notice that the keys were
26
NOT preserved.
27
array
28
'name' => string 'Sarah'
29
'age' => int 27
The groupBy
method can be instructed to preserve keys by passing true
for the $preserveKeys
parameter:
1
// Group the collection while preserving keys.
2
$grouped
=
$collection
->
groupBy
(
'age'
,
true
);
The $grouped
variable would now contain a value similar to the following output:
1
object(Illuminate\Support\Collection)
2
'items' =>
3
array
4
30 =>
5
object(Illuminate\Support\Collection)
6
protected 'items' =>
7
array
8
'first' =>
9
^== Notice that keys WERE preserved.
10
array
11
'name' => string 'Dave'
12
'age' => int 30
13
'second' =>
14
^== Notice that keys WERE preserved.
15
array
16
'name' => string 'Jim'
17
'age' => int 30
18
27 =>
19
object(Illuminate\Support\Collection)
20
protected 'items' =>
21
array
22
'third' =>
23
^== Notice that keys WERE preserved.
24
array
25
'name' => string 'Sarah'
26
'age' => int 27
∎