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.
Output: PHP script
<?php
$words = ["one", "two", "three", "four", "five"];
// Appending to a key that does not exist yet starts a new group.
$byFirstLetter = [];
foreach ($words as $w) {
$key = strtoupper($w[0]);
$byFirstLetter[$key][] = $w;
}
echo json_encode($byFirstLetter), "\n";
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].
Output: PHP script
<?php
$words = ["one", "two", "three", "four", "five"];
$groups = [];
foreach ($words as $w) {
$key = $w[0]; // lower-case first letter
$value = strtoupper($w); // the value stored in the group
$groups[$key][] = $value;
}
echo json_encode($groups), "\n";
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.
Output: PHP script
<?php
$words = ["one", "two", "three", "four", "five"];
// array_count_values() counts how often each value appears.
$letters = array_map(fn($w) => $w[0], $words);
$counts = array_count_values($letters);
echo json_encode($counts), "\n";
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.
Output: PHP script
<?php
$numbers = [3, 4, 5, 6, 7, 8];
// A missing key falls back to 0 with ??, so adding needs no special case.
$sums = [];
foreach ($numbers as $n) {
$key = $n % 2 === 0 ? "even" : "odd";
$sums[$key] = ($sums[$key] ?? 0) + $n;
}
echo json_encode($sums), "\n";
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.
Output: PHP script
<?php
$numbers = [3, 4, 5, 6, 7, 8];
$chains = [];
foreach ($numbers as $n) {
$key = $n % 2 === 0 ? "even" : "odd";
// The first number of a group starts the string; later ones join with "+".
if (!isset($chains[$key])) {
$chains[$key] = (string)$n;
} else {
$chains[$key] .= "+" . $n;
}
}
echo json_encode($chains), "\n";