Start learning free

LESSON 274 OF 678 · TUPLES, SORTING & BUILT-INS

Min, Max and Sum in Swift: min(), max() and reduce

Lesson Read the full explanation

TL ; DR:

arr.min() and arr.max() give the smallest and the largest value of an array, as optionals.

arr.reduce(0, +) adds all the values up.


let prices = [4, 9, 2, 7]

print(prices.min()!)          // 2
print(prices.max()!)          // 9
print(prices.reduce(0, +))    // 22


Full lesson:

In Maximum Number In Array, a loop found the largest value. In Sum of Numbers, a loop added numbers up. These jobs come up all the time. Swift arrays have ready-made methods for them.

  • arr.min() gives the smallest value of the array arr.
  • arr.max() gives the largest value.
  • arr.reduce(0, +) adds all the values up.

min() and max() return an optional. An empty array has no smallest value, so they give nil there. The ! takes the value out, as in Optionals & Unwrapping.

Swift has no sum(). reduce(0, +) starts at 0 and adds each value with +, from left to right.

The global max(a, b) from Maximum Number In Array compares two values. arr.max() looks at a whole array.

Watch out for an empty array. There, arr.min()! crashes, because the ! finds nil. When the array may be empty, write arr.min() ?? 0 for a fallback. reduce(0, +) of an empty array is 0.


Your task

minutes holds how many minutes you practiced coding on each day of a week.

Store the shortest day in shortest and the longest day in longest. Store the week's total in total.

Use the built-ins from this lesson. The code at the bottom prints all three.

Expected output:

shortest = 15
longest = 60
total = 235
STEP 1 OF 3
    Ctrl + Enter to check

    SWIFT · TUPLES, SORTING & BUILT-INS

    Min Max Sum in Swift, explained

    Ready-made methods

    Finding the largest value or adding numbers up are jobs you can write with a loop, and they come up all the time. Swift arrays have methods for them:

    let prices = [4, 9, 2, 7]
    print(prices.min()!)
    print(prices.max()!)
    print(prices.reduce(0, +))
    
    2
    9
    22
    
    • arr.min() gives the smallest value of the array.
    • arr.max() gives the largest value.
    • arr.reduce(0, +) adds all the values.

    Why min() and max() need a !

    min() and max() return an optional. An empty array has no smallest value, so for it they give nil. The ! takes the value out of the optional. When you know the array has at least one item, as with the seven days in this lesson, the ! is safe.

    For an empty array, arr.min()! crashes the program, because the ! finds nil. When the array may be empty, supply a fallback with ??:

    let none: [Int] = []
    print(none.min() as Any)
    print(none.min() ?? 0)
    print(none.reduce(0, +))
    
    nil
    0
    0
    

    These methods work on any array whose items can be compared. For strings, ["pear", "apple", "fig"].min()! is "apple" and the max() is "pear", by alphabetical order.

    Without the ! or ??, you can't use the value as a number. nums.min() + 1 is rejected with "value of optional type 'Int?' must be unwrapped to a value of type 'Int'".

    reduce and the missing sum()

    Swift has no sum() method. reduce(0, +) fills the gap. It starts at 0 and combines the running total with each value using +, from left to right. The result for an empty array is the start value, 0, so no ! is needed. The same total can be written with an explicit closure, reduce(0) { $0 + $1 }, which gives the same answer. In reduce(0, +), the plain operator + is passed in place of that closure.

    It works for other number types too: [2.5, 1.5].reduce(0, +) is 4.0. The start value takes the type of the items.

    The global max(a, b) compares two values. arr.max() looks at a whole array. For example, max(3, 8) is 8.

    The lesson's exercise

    minutes holds the minutes practiced on each day of a week. The task stores the shortest day in shortest, the longest in longest and the week's total in total:

    1. let shortest = minutes.min()! takes the smallest value, 15.
    2. let longest = minutes.max()! takes the largest, 60.
    3. let total = minutes.reduce(0, +) adds the seven values: 235.
    let minutes = [25, 40, 15, 60, 30, 45, 20]
    let shortest = minutes.min()!
    let longest = minutes.max()!
    let total = minutes.reduce(0, +)
    print("shortest = \(shortest)")
    print("longest = \(longest)")
    print("total = \(total)")
    

    The output is:

    shortest = 15
    longest = 60
    total = 235
    

    Compared with a loop, the methods save the starting value and the update step. A loop that finds the largest value needs a start such as the first item, then an if inside the loop; arr.max() does all of that, and its optional result also covers the empty-array case that a loop would have to handle on its own.

    Common mistakes

    • Calling sum(). It doesn't exist on arrays. Use reduce(0, +).
    • Forgetting the start value. reduce(+) doesn't compile: the compiler reports a missing argument, because the first argument is the value to start from.
    • Leaving out the !. The constant would then hold an Int?, and the string would print Optional(15) instead of 15.
    • Using ! on a possibly empty array. That crashes. Use ?? 0 or check isEmpty first.

    Key takeaways

    • min() and max() return optionals, which are nil for an empty array.
    • ! is fine when the array can't be empty; ?? gives a fallback when it can.
    • reduce(0, +) is Swift's sum, and it gives 0 for an empty array.
    Keep going with Swift500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free