Problem overview
The function count receives a slice of integers, nums, and an integer value. It returns how many times value appears in nums. The task asks you to write the loop yourself instead of calling a ready-made function.
For nums = [1, 4, 2, 2, 5, 2] and value = 2, the 2 sits at three positions, so the answer is 3.
Approach
This is the basic counting pattern. Keep a counter that starts at 0, look at every element once, and add 1 to the counter each time the element equals value. When the loop ends, the counter holds the answer.
Every element has to be inspected, because any of them might match. Unlike a search for the first match, there is nothing to stop early for.
Tracing the example
With nums = [1, 4, 2, 2, 5, 2] and value = 2, the counter changes like this as the loop moves through the slice:
- 1 is not 2, so
answerstays 0. - 4 is not 2, so it stays 0.
- 2 matches, so
answerbecomes 1. - The next 2 matches, so
answerbecomes 2. - 5 does not match, so it stays 2.
- The last 2 matches, so
answerbecomes 3.
The loop ends and the function returns 3. The same pattern, a counter plus a condition inside a loop, answers many similar questions: how many even numbers there are, how many grades are below a limit, how many characters are vowels. Only the condition changes.
Step by step
- Create the counter.
answer := 0declares anintand infers its type from the literal. It must be declared before the loop, otherwise it would be reset on every pass. - Loop over the slice with
for ... range. Each iteration produces an index and an element. Only the element matters, and Go rejects declared-but-unused variables, so the index is discarded with_. - Compare and count. Inside the loop, an
ifchecks whethernum == valueand incrementsansweron a match. Elements that differ are skipped. - Return after the loop. A
returninside the loop would end the function after the first element.
The solution in Go
func count(nums []int, value int) int {
answer := 0
for _, num := range nums {
if num == value {
answer++
}
}
return answer
}
The Go details worth knowing:
++is a statement. In Go,answer++is a complete statement on its own line, not an expression. Code such asx := answer++orreturn answer++does not compile.- No parentheses around conditions. Go writes
if num == value {with no parentheses, and the braces are required even for a one-line body. - Elements are copies.
numis a copy of the current element. That is fine here because the function only reads the values. Changingnumwould not change the slice. - The type is
[]int, a slice. The lesson calls it an array, but a slice is what Go code normally passes around.rangeandlenwork the same on both.
Complexity
Time: O(n). The loop makes one pass, with a constant amount of work per element.
Space: O(1). The function keeps one counter and the loop variable.
Edge cases and common mistakes
- Value not present. The counter never changes, so the function returns 0.
- Empty or
nilslice. The loop body runs zero times and the function returns 0. Ranging over anilslice is safe in Go. - Every element matches. For
[]int{3, 3, 3}and 3, the result is 3. - Declaring the counter inside the loop. It would restart at 0 on every pass, and the code would not compile anyway, because
answerwould not exist at thereturn. - Returning inside the loop. The function would stop after the first element.
- Using the index as the count. The index tells you where an element is, not how many matches have been seen.
Testing
[]int{1, 4, 2, 2, 5, 2}with 2 gives3.[]int{1, 4, 2, 2, 5, 2}with 7 gives0.[]int{3, 3, 3}with 3 gives3.[]int{}with 1 gives0.