Finding an Array’s Minimum and Maximum Values in Swift

You are suddenly blasted with an unending amount of numbers. It’s a battle royal. You don’t care about all the individual competitors. You want to know the strongest there is. And maybe the weakest, so you can have something to compare the strongest to. You want to find out the minimum and maximum values of an array of numbers!

The One Word Method

Why mess with multiple words when you can do it all with just one. min() and max() come jam packed with the functionality you already need.

You may have seen these before when you were just comparing two numbers.

let minimumValue = min(1, 10)
//1
let maximumValue = max(1, 10)
//10

The same functionality can work its wonders on an array as well.

let battleRoyal = [2, 35, 14, 88, 54]
let battleRoyalStrongest = battleRoyal.max()
let battleRoyalWeakest = battleRoyal.min()
//And the winner and ultimate loser is...?

You would think that 88 and 2 would emerge. However, you get:

Optional(88)
Optional(2)

No one wants to be optional, especially not the grand champion. The problem with battle royals, like with arrays, is sometimes there are no-shows. If you declare an array with nothing inside it, there is no minimum or maximum – there is only void, and a nice big error.

//Declare a blank array of Integers
let battleRoyal: [Int]()

let battleRoyalStrongest = battleRoyal.max()
//Error!

To be safe, and make sure someone is in the arena, the value that results from the min() or max() function is optional. To get rid of that optional title, you need to handle the optional properly. Two example ways of doing this are provided below.

//Unwrap the optional using optional binding
let battleRoyal = [2, 35, 14, 88, 54]
if let battleRoyalStrongest = battleRoyal.max() {
    print(battleRoyalStrongest)
} else {
    print("It was a no-show!")
}
//Using the nil-coalescing operator to provide a default value
let battleRoyal = [Int]()
let battleRoyalStrongest = battleRoyal.max() ?? 0
//0

That one word method wasn’t as short as you thought…

Sort and choose your winner

Rather than just randomly take all of the fighters, sorting them first is another easy way to figure out the two extremes.

let battleRoyal = [2, 35, 14, 88, 54]
let battleRoyalSorted = battleRoyal.sorted(by: <)
//[2, 14, 35, 54, 88]

Now that you’ve lined everybody up, you can find out the first and last values of the newly created array battleRoyalSorted.

let battleRoyal = [2, 35, 14, 88, 54]
let battleRoyalSorted = battleRoyal.sorted(by: <)

//First value in the array (index starts at 0)
let battleRoyalWeakest = battleRoyalSorted[0]

//Last value in the array
let battleRoyalStrongest = battleRoyalSorted[battleRoyal.count - 1]

print ("Strongest: \(battleRoyalStrongest), Weakest: \(battleRoyalWeakest)")

Similar to the no-show situation above, if you try to run the above on an empty array, you’ll get an error (index out of range). Make sure to do a check to see whether the array is empty.

let battleRoyal = [2, 35, 14, 88, 54]
let battleRoyalSorted = battleRoyal.sorted(by: <)

if !battleRoyal.isEmpty {
    print("Weakest: \(battleRoyalSorted[0])")
    print("Strongest: \(battleRoyalSorted[battleRoyal.count - 1])")
} else {
    print ("No one showed up!")
}

The “You do the Calculations” Way

The strongest and weakest don’t believe in the hidden judge. They want to see behind the scenes of how you calculated their ranking. It will take a little more work iterating through the array, but everything still works out.

let battleRoyal = [2, 35, 14, 88, 54]
var battleRoyalStrongest = 0

for (index, value) in battleRoyal.enumerated() {
    if (battleRoyal[index] > battleRoyalStrongest){
       battleRoyalStrongest = battleRoyal[index]
    }
}

print (battleRoyalStrongest)

With the above, you are iterating through the battleRoyal array, and checking whether each value is greater than the initial battleRoyalStrongest value of 0. If it is, you update the battleRoyalStrongest with that new value. The benefit of this is there is no worry about the array being blank, because you are giving a default value to the maximum of 0.

Or maybe you want to go really crazy with advanced functionality. How about the example that the Apple Swift documentation gives:

func weakestStrongest(battleRoyal: [Int]) -> (min: Int, max: Int)? {
    if battleRoyal.isEmpty { return nil }
    var currentMin = battleRoyal[0]
    var currentMax = battleRoyal[0]
    for value in battleRoyal[1..<battleRoyal.count] {
        if value < currentMin {
            currentMin = value
        } else if value > currentMax {
            currentMax = value
        }
    }
    return (currentMin, currentMax)
}

if let bounds = weakestStrongest(battleRoyal: [2, 35, 14, 88, 54]) {
    print("Weakest: \(bounds.min) Strongest: \(bounds.max)")
} else {
    print ("No one showed up!")
}
  1. The function weakestStrongest takes an array of Integers (the combatants)
  2. The function returns an optional tuple of minimum and maximum Integers
  3. The function first checks whether the array is empty, possibly returning nil
  4. If the array wasn’t empty, then the first minimum and maximum values are set to the first index of the array
  5. Iterate through the array replacing the minimum and maximum values if the next index would be a new (lower) minimum or (higher) maximum
  6. The function returns the results of the lowest minimum and highest maximum
  7. The optional tuple values returned from the function are unwrapped

This last one is hard. If you don’t get it on the first, second, or tenth read, don’t worry.

Found your champion?

You have a lot of options for your battle royal. Which will you choose?

Leave a Comment

Your email address will not be published. Required fields are marked *