Start learning free

LESSON 246 OF 671 · HELPER FUNCTIONS

Clamp All in Go: A Helper Function Used in a Loop

Practice Read the full explanation

You get an array of integers nums and two limits, low and high. Return every number moved inside the limits, in the same order.

A number below low becomes low. A number above high becomes high. Any other number stays as it is.

The work is split between two functions. The first one is a helper. It gets one number and the two limits. It returns that number moved inside them. The second one is the function that is graded. It calls the helper on every number.

Don't use a built-in min, max or clamp function. The helper does the comparing.

 

Example 1:

Input: nums = [12, -3, 7, 25], low = 0, high = 20
Output: [12, 0, 7, 20]
Explanation: -3 is below 0, so it becomes 0.
25 is above 20, so it becomes 20.
12 and 7 are already inside the limits.

Example 2:

Input: nums = [-8, -1, 4], low = -5, high = 5
Output: [-5, -1, 4]
Explanation: The limits can be negative too.
-8 is below -5, so it becomes -5.
-1 and 4 stay as they are.

Example 3:

Input: nums = [3, 9, 6], low = 6, high = 6
Output: [6, 6, 6]
Explanation: Both limits are 6, so every number becomes 6.

 

Constraints:

  • nums has at least one number.
  • Every number is between -1000 and 1000.
  • low and high are between -1000 and 1000.
  • low is never greater than high.
STEP 1 OF 7
    Ctrl + Enter to check

    GO · HELPER FUNCTIONS

    Clamp All in Go, explained

    Problem overview

    You get a slice of integers nums and two limits, low and high. Return 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.

    For nums = [12, -3, 7, 25] with limits 0 and 20, the answer is [12 0 7 20]. With limits -5 and 5, the numbers [-8, -1, 4] become [-5 -1 4]. When low and high are both 6, every number becomes 6.

    Approach

    The work splits in two. A helper, clamp, decides what happens to one number. The graded function, clampAll, only walks the slice and calls the helper on each element. Splitting it this way means the comparing is written once, in a function you can test on its own, and the loop stays free of if statements.

    Step by step

    The helper clamp(x, low, high):

    1. If x < low, return low.
    2. If x > high, return high.
    3. Otherwise return x. Only a number between the limits reaches this line, so no else is needed.

    The function clampAll(nums, low, high):

    1. Create an empty slice clamped := []int{}.
    2. Loop with for _, num := range nums.
    3. Append clamp(num, low, high) and assign the result back to clamped.
    4. Return clamped after the loop.

    The solution in Go

    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 {
        clamped := []int{}
        for _, num := range nums {
            clamped = append(clamped, clamp(num, low, high))
        }
        return clamped
    }
    

    Two Go details: append returns the (possibly reallocated) slice, so you assign it back to clamped; and range gives an index and a value, so the unused index is written as _. The built-in min and max that Go has since version 1.21 are deliberately left out here: the helper does the comparing.

    How the helper treats each number

    Calling clamp on each number of the first example, with limits 0 and 20, gives:

    12 -> 12
    -3 -> 0
    7 -> 7
    25 -> 20
    

    The order of the two if statements does not matter, because low is never greater than high: no number can be both below low and above high. When the limits are equal, as in the third example, every number is either below, above or exactly equal to the single limit, and the helper returns that limit in all three cases.

    Why a helper

    A helper is a function whose only job is to make another function simpler. Here clampAll would work without one, but it would carry two if statements inside its loop and be harder to read. With the helper, the loop says exactly what it does: it clamps each number. If the rule changed later, you would edit one small function and the loop would stay as it is.

    Both functions sit side by side at the top level of the program. A call to clamp inside clampAll needs no special syntax; it is an ordinary function call, with the arguments in the same order as the parameters.

    A new slice, not a changed one

    The function builds a new slice and leaves nums as it was. That matches the statement, which asks to "return" the clamped numbers. It also avoids a surprise that comes from how slices work: a slice passed to a function shares its underlying array with the caller, so writing into nums[i] would change the caller's data too.

    Two ways to write the parameters

    The lesson writes each parameter with its own type: x int, low int, high int. Go also lets neighbouring parameters of the same type share one type name, so func clamp(x, low, high int) int means the same thing. Both forms compile and behave identically. The first form is spelled out in the lesson because it is easier to read at the start.

    The helper can also be tried alone. With limits 0 and 10, clamp(15, 0, 10) gives 10, clamp(-4, 0, 10) gives 0 and clamp(6, 0, 10) gives 6. A number below the range moves up to the lower limit, a number above it moves down to the upper limit, and a number inside the range is returned untouched.

    Testing

    [12 -3 7 25], low 0, high 20   ->  [12 0 7 20]
    [-8 -1 4], low -5, high 5      ->  [-5 -1 4]
    [3 9 6], low 6, high 6         ->  [6 6 6]
    

    Edge cases

    A number that sits exactly on a limit is already inside the range. Neither x < low nor x > high is true for it, so it falls through to return x unchanged. Negative limits behave like any others, and the comparisons need no special care. The slice always has at least one number, and the output has exactly as many elements as the input, because the loop appends once per number. With both limits equal, every element comes back as that limit, whatever it was, as in the third example. The helper never changes the count of numbers, only their values.

    Common mistakes

    • Returning inside the loop. That hands back after the first number. The return goes after the loop.
    • Using else if on the wrong branch or returning the wrong limit. Below low returns low; above high returns high.
    • Writing the comparisons in the loop. The helper exists so that the loop needs no if.
    • Forgetting to assign append's result, which leaves clamped empty.
    Keep going with Go500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free