Problem overview
The function clampAll receives an array of integers nums and two limits, low and high. It returns every number moved inside the limits, in the same order. A number below low becomes low, a number above high becomes high, and any other number stays as it is. The limits satisfy low <= high, and built-in min, max or clamping functions are off limits.
For nums = [12, -3, 7, 25] with limits 0 and 20, the answer is [12, 0, 7, 20]. For [-8, -1, 4] with limits -5 and 5 it is [-5, -1, 4]. For [3, 9, 6] with both limits 6 it is [6, 6, 6].
Approach: one small function, called for each number
The lesson splits the work in two. The helper clamp handles one number, and clampAll only loops and calls the helper. Each function does one job, and the helper can be tested alone: clamp(25, 0, 20) is 20, clamp(-3, 0, 20) is 0 and clamp(12, 0, 20) is 12.
Inside clamp, the number is in one of three places: below the range, above it, or inside. Two if statements with an early return cover the first two. If neither fires, the number is inside, and the function returns it unchanged.
Step by step
- Below the range. If
x < low, returnlow. - Above the range. If
x > high, returnhigh. - Inside. Return
x. Only a number between the limits reaches this line, so noelseis needed. - Start the second function with an empty array,
var clamped = [Int](). It needsvarbecause it grows. - Loop over
numswithfor num in nums, once per number. - Append the helper's answer:
clamped.append(clamp(num, low, high)). The loop has noifof its own. - Return
clampedafter the loop. Returning inside it would send back only the first number.
The solution in Swift
class Solution {
func clamp(_ x: Int, _ low: Int, _ high: Int) -> Int {
if x < low {
return low
}
if x > high {
return high
}
return x
}
func clampAll(_ nums: [Int], _ low: Int, _ high: Int) -> [Int] {
var clamped = [Int]()
for num in nums {
clamped.append(clamp(num, low, high))
}
return clamped
}
}
Swift details: both functions are methods of the class, so clampAll can call clamp by its plain name. The underscores in _ x: Int mean the caller writes no argument labels, which is why the call reads clamp(num, low, high).
Why a helper is worth it
A helper gives a name to one small idea, "move this number inside the limits", so the main function reads as what it does: clamp each number. It also means the comparing is written once. If the rule ever changed, only clamp would need editing, and clampAll would keep working.
The order of the two if checks does not matter, because the limits satisfy low <= high: no number can be both below low and above high. If the limits were swapped, that would stop being true, which is why the lesson promises low is never greater than high.
The helper alone
With the limits 0 and 20, clamp gives these results:
| x | clamp(x, 0, 20) | Why |
|---|---|---|
| -3 | 0 | below the range |
| 0 | 0 | on the lower limit, unchanged |
| 12 | 12 | inside |
| 20 | 20 | on the upper limit, unchanged |
| 25 | 20 | above the range |
A number exactly on a limit is already inside, so it is left alone. That is why the comparisons use < and >, not <= and >=, although with <= the answer would be the same value either way.
The three examples give:
[12, 0, 7, 20]
[-5, -1, 4]
[6, 6, 6]
When both limits are equal, any number lands on that value: clamp(9, 6, 6) and clamp(3, 6, 6) both return 6.
Another way, once built-ins are allowed
The lesson asks you to do the comparing yourself, but it is worth knowing what Swift offers in a program of your own. The standard min and max functions give a one-line clamp: min(max(x, low), high) returns 20 for x = 25 with limits 0 and 20, and 0 for x = -3. For the loop, nums.map { clamp($0, low, high) } builds the same array as the for loop. On [12, -3, 7, 25] with limits 0 and 20 it returns [12, 0, 7, 20]. The explicit loop is clearer for a first lesson, since each step is visible.
Edge cases
If every number is already inside the limits, the output equals the input: [1, 2, 3] with limits 0 and 10 returns [1, 2, 3]. A one-number array works the same way, and [5] with both limits 5 returns [5]. Negative limits need no special handling, since the comparisons work on any integers.
Reading the result
Each output position matches the input position: the number at index 0 of nums becomes the number at index 0 of the result, so the array keeps its length and its order. The function does not sort, drop or reorder anything. In the first example, 12 and 7 come out as they went in, -3 comes out as 0, and 25 comes out as 20, all in their original places.
Common mistakes
- Adding an
elsewhere none is needed. After anifthat returns, the code below it only runs when the condition was false, so a followingelsewould repeat what is already known. - Swapping the two comparisons' results. Below the range must return
low, and above it must returnhigh. - Doing the comparing in
clampAll. The lesson wants that work in the helper. - Changing the input. The function builds a new array. The parameter
numsis a constant, and the result is separate.
