Walk a sequence and count occurrences of each value in a map. Classic "get current count, add one, write back" loop.

Algorithm

Canonical input ["fig", "apple", "fig", "pear", "apple", "fig"] produces the final map {fig: 3, apple: 2, pear: 1}.

Basic Implementation

basic.php
<?php
$words = ["fig", "apple", "fig", "pear", "apple", "fig"];
$counts = [];
$order = [];
$i = 0;
while ($i < count($words)) {
	$word = $words[$i];
	if (!array_key_exists($word, $counts)) {
		$order[] = $word;
		$counts[$word] = 1;
	} else {
		$prev = $counts[$word];
		$counts[$word] = $prev + 1;
	}
	$i = $i + 1;
}
echo "{";
$j = 0;
while ($j < count($order)) {
	if ($j > 0) {
		echo ", ";
	}
	$key = $order[$j];
	echo "$key: " . $counts[$key];
	$j = $j + 1;
}
echo "}\n";

Complexity

  • Time: O(n) average with PHP associative arrays (hash-table backed).
  • Space: O(k) where k is the number of distinct keys.

Implementation notes

  • PHP: $counts = []; is the idiomatic associative array; the !array_key_exists($word, $counts) predicate plus an explicit assignment keeps the lesson on the read-or-default path without hiding it behind ??= or array_count_values($words).
  • The auxiliary $order buffer makes the first-seen order explicit so the final printout does not lean on PHP's insertion-order iteration as a contract.
  • The replay renders the map as a list of key/value rows in first-seen order and animates the count increment on each frame.
get-or-default A first-time `$word` triggers the "default" branch: append to `$order` and set `$counts[$word] = 1`. A repeat read-modify-writes `$counts[$word] = $prev + 1`.
first-seen order Keys are tracked in `$order` (a plain indexed array) to keep the printout deterministic; PHP associative-array iteration order happens to be insertion order but the lesson does not lean on that contract.