Start learning free

LESSON 242 OF 671 · HELPER FUNCTIONS

Clamp All in JavaScript with a Helper Method

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

    JAVASCRIPT · HELPER FUNCTIONS

    Clamp All in JavaScript, explained

    Problem overview

    The method clampAll gets an array of integers nums and two limits, low and high, and 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 are never reversed: low is not greater than high.

    For nums = [12, -3, 7, 25] with limits 0 and 20, the answer is [12, 0, 7, 20]: -3 is below 0 and 25 is above 20. With negative limits -5 and 5, [-8, -1, 4] becomes [-5, -1, 4]. With both limits equal to 6, every number becomes 6.

    Approach: split the work in two

    The lesson has two methods. The helper clamp deals with one number: it compares it with the limits and returns the number moved inside them. clampAll only loops over the array and calls the helper for each number. The loop doesn't need an if of its own, because the helper does all the comparing.

    The split makes each part small. You can test clamp on single numbers before using it in the loop, and the loop reads as one sentence: for each number, push its clamped value.

    Step by step

    1. In clamp, handle the low side: if x < low, return low.
    2. Handle the high side: if x > high, return high.
    3. Return x after both checks. Only a number between the limits gets here, and it stays as it is, so no else is needed.
    4. In clampAll, start with an empty array named clamped.
    5. Loop over nums with for (let num of nums).
    6. Push the helper's answer: this.clamp(num, low, high). Each number gives exactly one clamped number.
    7. Return clamped after the loop.

    The solution in JavaScript

    class Solution {
        clamp(x, low, high) {
            if (x < low) {
                return low;
            }
            if (x > high) {
                return high;
            }
            return x;
        }
        clampAll(nums, low, high) {
            let clamped = [];
            for (let num of nums) {
                clamped.push(this.clamp(num, low, high));
            }
            return clamped;
        }
    }
    

    Inside a class, one method calls another through this: this.clamp(...). Writing just clamp(...) looks for a plain function or variable with that name, and since there isn't one, JavaScript throws "clamp is not defined".

    The early return in the first if ends the method, so the second check only runs for numbers that weren't below low. That is why two separate if statements are enough.

    Testing

    On the statement's examples, with the values separated by spaces:

    12 0 7 20
    -5 -1 4
    6 6 6
    

    The helper on single numbers: clamp(-3, 0, 20) returns 0, clamp(25, 0, 20) returns 20, and clamp(7, 0, 20) returns 7.

    Following the first example

    With nums = [12, -3, 7, 25], low = 0 and high = 20, the loop calls the helper four times. The call this.clamp(12, 0, 20) passes both checks and returns 12. The call this.clamp(-3, 0, 20) is caught by the first check and returns 0. The call this.clamp(7, 0, 20) returns 7. The call this.clamp(25, 0, 20) passes the first check, is caught by the second, and returns 20. The pushes build clamped one value at a time, so after the loop it holds 12 0 7 20, in the same order as nums.

    Edge cases

    • A number exactly on a limit. clamp(0, 0, 20) returns 0 and clamp(20, 0, 20) returns 20. The checks use strict comparisons, < and >, so a number equal to a limit falls through to return x, which gives the same value anyway.
    • Equal limits. With low = high = 6, 3 becomes 6 through the first check, 9 becomes 6 through the second, and 6 stays 6. Every result is 6.
    • One number. clampAll([5], 1, 10) returns an array with the single value 5.
    • The input stays as it was. After clampAll([12, -3, 7, 25], 0, 20) runs, the original array still reads 12 -3 7 25, because the results go into a new array.

    Another way

    An array's map method builds a new array by calling a function on every element, which is exactly what the loop does. With an arrow function, this keeps pointing at the object, so the helper call looks the same:

    clampAllMap(nums, low, high) {
        return nums.map(num => this.clamp(num, low, high));
    }
    

    Placed next to the other two methods, it returns 12 0 7 20 on the first example. The lesson's tests call clampAll, and the loop makes each step visible, so the loop is the version to write in the editor. Notice that the helper is the same in both: splitting the comparing from the looping is what lets the looping part change without touching the rest.

    A good habit with helpers is to check them alone first. If clamp(-3, 0, 20) returns 0 and clamp(25, 0, 20) returns 20, then any wrong answer from clampAll must come from the loop, not from the comparing.

    Common mistakes

    • Calling clamp without this., which throws "clamp is not defined". Inside the class, always reach the helper through this.
    • Returning inside the for loop. Only the first number would come back, and the rest of the array would never be visited. Return after the loop.
    • Swapping the limits in a comparison. Check x < low to return low, and x > high to return high.
    • Changing nums instead of building a new array. The method should return a fresh array; pushing into clamped leaves the input untouched.
    Keep going with JavaScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free