Start learning free

LESSON 247 OF 678 · HELPER FUNCTIONS

Clamp All in Swift: A Helper Function Inside 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

    SWIFT · HELPER FUNCTIONS

    Clamp All in Swift, explained

    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

    1. Below the range. If x < low, return low.
    2. Above the range. If x > high, return high.
    3. Inside. Return x. Only a number between the limits reaches this line, so no else is needed.
    4. Start the second function with an empty array, var clamped = [Int](). It needs var because it grows.
    5. Loop over nums with for num in nums, once per number.
    6. Append the helper's answer: clamped.append(clamp(num, low, high)). The loop has no if of its own.
    7. Return clamped after 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:

    xclamp(x, 0, 20)Why
    -30below the range
    00on the lower limit, unchanged
    1212inside
    2020on the upper limit, unchanged
    2520above 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 else where none is needed. After an if that returns, the code below it only runs when the condition was false, so a following else would repeat what is already known.
    • Swapping the two comparisons' results. Below the range must return low, and above it must return high.
    • Doing the comparing in clampAll. The lesson wants that work in the helper.
    • Changing the input. The function builds a new array. The parameter nums is a constant, and the result is separate.
    Keep going with Swift500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free