Problem overview
The function firstN receives a slice of integers, nums, and a number n. It returns a slice with the first n numbers of nums, in the same order. The constraints promise that n is between 0 and the length of nums.
For nums = [3, 8, 1, 9, 4] and n = 3 the result is [3 8 1]: the 9 and the 4 are left out. When n is 0 the result is empty, and when n equals the length every number is kept.
Approach
Go can take a piece of a slice directly. nums[:n] has the items at indexes 0 to n - 1: the end index is not included, and leaving out the start means 0. So the slice expression already has the right length, n, and no loop is needed.
You could also build the answer yourself: start from an empty slice and append nums[i] for each i from 0 up to n - 1. That gives the same results ([3 8 1] for the first example, an empty slice for n = 0), but it takes a loop, a variable and an append where the slice expression needs one line.
Think of the end index as "stop before". With n = 3 the slice stops before index 3, so it holds indexes 0, 1 and 2, which are three items. In general nums[:n] has exactly n items, which is why n can be used as the end index directly.
Step by step
- Slice
numsfrom the start up to indexnand keep it inresult, declared with:=. - Return
result.
The solution in Go
func firstN(nums []int, n int) []int {
result := nums[:n]
return result
}
The returned slice is a view onto the same memory as nums, not a copy. Changing an item of one changes the other, and appending to the result can overwrite the item that follows it in nums. With nums = [3, 8, 1, 9, 4], f := firstN(nums, 3) followed by f = append(f, 100) leaves nums as [3 8 1 100 4]. Here nothing modifies either slice, so sharing is harmless. If a caller needed an independent copy, slices.Clone(nums[:n]) would give one.
Testing
These inputs and results come from running the function:
| nums | n | result |
|---|---|---|
[3 8 1 9 4] | 3 | [3 8 1] |
[5 6 7] | 0 | [] |
[2 4] | 2 | [2 4] |
For n = 0 the result has length 0 and is not nil: nums[:0] is an empty slice that still points into nums. It prints as [], which is what the lesson expects.
Edge cases and common mistakes
The two ends of the range are the interesting inputs: n = 0, where nothing is taken, and n = len(nums), where everything is taken. Both work with the same code, because the slice expression allows an end index from 0 up to the length of the slice.
- Using
n - 1as the end. That drops the last wanted item, because the end index is not included. Forn = 3you would get two numbers. - An
nlarger than the slice. The constraints rule it out, but in a program of your ownfirstN([]int{1, 2}, 3)panics withslice bounds out of range [:3] with capacity 2. Checknagainstlen(nums)first if the input isn't trusted. - Writing a loop and an
appendfor something one slice expression does. It works, but it is longer and easier to get wrong.
