Start learning free

LESSON 246 OF 675 · HELPER FUNCTIONS

Clamp All in TypeScript: Calling 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

    TYPESCRIPT · HELPER FUNCTIONS

    Clamp All in TypeScript, explained

    Problem overview

    The method clampAll receives 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 at most high. The task bans the built-in min and max, so the comparing is done by hand.

    For [12, -3, 7, 25] with limits 0 and 20, the result is [12, 0, 7, 20]: -3 is below 0, 25 is above 20, and the others are inside. For [3, 9, 6] with both limits equal to 6, every number becomes 6.

    Approach: one helper for one number

    The lesson splits the work into two methods. The helper, clamp, solves the problem for a single number: it takes x and the two limits and returns x moved inside them. The main method, clampAll, only loops over the array and calls the helper for each number.

    That split keeps both pieces small. The helper has no loop, and the loop has no if. You can test the helper alone, for example clamp(25, 0, 20) is 20, clamp(-3, 0, 20) is 0 and clamp(7, 0, 20) is 7.

    Step by step

    1. In clamp, check the low side. If x < low, return low.
    2. Check the high side. If x > high, return high.
    3. Return x. Only a number between the limits gets here, and it stays as it is. No else is needed, because each return ends the method.
    4. In clampAll, create clamped, an empty number[].
    5. Loop over nums with for (const num of nums).
    6. Push the helper's answer for num onto clamped, calling the helper as this.clamp(num, low, high).
    7. Return clamped after the loop.

    The solution in TypeScript

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

    The part specific to TypeScript is how one method calls another:

    • this. is required. Inside a class, a method is reached through this. Writing plain clamp(num, low, high) looks for a function or variable called clamp outside the class. The compiler reports "Cannot find name 'clamp'" and suggests this.clamp, and the JavaScript it still writes stops with clamp is not defined when that line runs.
    • The result is a new array. nums is not modified. push adds to clamped, which starts empty.
    • Parameter types are not checked at run time. The annotations help the compiler, but the compiled JavaScript does not enforce them.

    Tracing the first example

    With limits 0 and 20, clampAll calls the helper once per number, and the helper answers like this:

    numhelper's answerwhy
    1212inside the limits
    -30below low
    77inside the limits
    2520above high

    Pushing those answers in order builds [12, 0, 7, 20]. The input array is still [12, -3, 7, 25] afterwards, because the method pushes into a separate array.

    Why a helper at all

    The comparing could be written directly inside the loop, with an if and an else if. The helper gives the rule a name, clamp, and makes the loop read as plain English: for each number, push its clamped value. When a program needs the same rule in a second place, it calls the helper again instead of copying the comparisons. A bug in the rule is then fixed once.

    Another way

    Array's map builds the new array for you, so the loop and the push disappear. The arrow function keeps this from the surrounding method, so the helper is still called as this.clamp:

    clampAll(nums: number[], low: number, high: number): number[] {
        return nums.map((num) => this.clamp(num, low, high));
    }
    

    On the first example it returns [12,0,7,20], the same as the loop. The lesson uses the explicit loop because it shows each step.

    The language does offer a one-line form, Math.min(Math.max(x, low), high), which gives 20, 0 and 7 for 25, -3 and 7 with limits 0 and 20. The task asks you not to use it, so that you practise the comparisons yourself and see why the order of the two tests does not matter when low is at most high: a number cannot be both below low and above high.

    Edge cases and common mistakes

    • Equal limits. With low == high every number is mapped to that value, because each one is either below, above or already equal to it.
    • Negative limits. [-8, -1, 4] with limits -5 and 5 gives [-5, -1, 4]. The comparisons work the same for negative numbers.
    • Numbers exactly on a limit. They fail both tests (x < low and x > high are both false) and are returned unchanged. Using <= or >= would still give the right value, only through a longer path.
    • Returning inside the loop. A return placed inside the for would send back just the first number's array.
    • Swapped limits. If the limits were reversed, clamp(5, 10, 0) would return 10, because the low test fires first. The task guarantees that never happens.

    Testing

    • [12, -3, 7, 25], 0, 20 gives [12, 0, 7, 20].
    • [-8, -1, 4], -5, 5 gives [-5, -1, 4].
    • [3, 9, 6], 6, 6 gives [6, 6, 6].
    • The helper alone: clamp(0, 0, 20) gives 0 and clamp(20, 0, 20) gives 20, so a number sitting exactly on a limit is returned as it is.
    Keep going with TypeScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free