Skip to main content

Grouping a Collection

Grouping means sorting elements into buckets. You choose a key for every element, and all elements with the same key land in the same bucket.

The key is computed from the element itself. For example, the first letter of a word.

PHP has no built-in groupBy function. The natural way to group is an associative array whose keys are the group keys and whose values are arrays of elements. One foreach loop fills it with $groups[$key][] = $element. Appending to a key that does not exist yet simply starts a new group — no special case is needed.

A PHP associative array keeps its insertion order: the groups appear in the order in which their first element arrived, and the printed output looks the same on every run.


Group By Key

The simplest grouping keeps the elements as they are and only decides which bucket each one goes to.

Compute the key inside the loop and append the element to $groups[$key]. The result maps each key to the array of elements with that key. The elements inside a group keep the order they had in the input.

Sometimes you want to change the elements while grouping, for example store them in upper case. Compute the key and the new value, then append the new value to the group.

Group words by first letter

$w[0] takes the first letter of the word and strtoupper() makes it upper case. Words that start with the same letter end up in the same array. The groups appear in insertion order: O, then T, then F.

Prompt
Group the words one, two, three, four, five by their upper-case first letter. Build an associative array in a foreach loop with $byFirstLetter[$key][] = $w and print it with json_encode.
Output: PHP script
Group words by first letter

Group and change the values

The key is the lower-case first letter. The stored value is the whole word in upper case. The loop computes both and appends the value to $groups[$key].

Prompt
Group the words one, two, three, four, five by their lower-case first letter. Store each word in its group in upper case, not as it was. Compute the key and the new value in a foreach loop, append with $groups[$key][] = $value, and print the array with json_encode.
Output: PHP script
Group and change the values

Count Each Group

Often you do not need the elements of each group, only how many there are.

PHP has a built-in counter: array_count_values(). It counts how often each value appears in an array. To count words per first letter, first turn every word into its first letter with array_map(), then let array_count_values() count the letters.

Count words per first letter

array_map() turns the words into the letters o, t, t, f, f. array_count_values() then counts each letter: one o, two t, two f.

Prompt
Count how many of the words one, two, three, four, five start with each letter. Turn the words into their first letters with array_map, count the letters with array_count_values, and print the result with json_encode.
Output: PHP script
Count words per first letter

Fold and Reduce per Group

Folding a group means combining its elements into one value, step by step. A running total is the classic example: start at 0 and add each element.

The PHP way is an associative array that holds the running value of every group. For each element, compute its key and update the value stored under that key.

Reading a key that is not in the array yet would raise a warning, so use the ?? operator: $sums[$key] ?? 0 quietly gives 0 when the key is missing. When the first element itself must start the value, check with isset() whether the key exists yet.

Sum each group

Each number is put in the group "even" or "odd" and added to that group's sum. ($sums[$key] ?? 0) + $n starts a new group at 0, so no special case is needed.

Prompt
Take the numbers 3, 4, 5, 6, 7, 8 and put each one in the group "even" or "odd". Add each number to the running sum of its group with $sums[$key] = ($sums[$key] ?? 0) + $n, so a missing key starts at 0. Print the array with json_encode.
Output: PHP script
Sum each group

Build a string per group

The first number of a group starts the string. Every later number is joined with "+". isset($chains[$key]) tells the two cases apart, and (string)$n turns the first number into text.

Prompt
Take the numbers 3, 4, 5, 6, 7, 8 and put each one in the group "even" or "odd". For each group build a string step by step: the first number starts the string, and every later number is appended with "+" in front, giving text like 3+5+7. Use isset to tell the two cases apart and print the array with json_encode.
Output: PHP script
Build a string per group