For-in loop and why it stops

I'm new Swift. The below exercise is teaching me how to assign multiple return values to a function. But it's the for-in loop that's confusing me. When I learned about these, the exercises always looped through all the possibilities in the array and then every one was included in the output. Why doesn't currentMax below get assigned every value in the array that is greater than its original value? It only gets assigned the maximum highest value. How does it know to only assign the highest value that meets the else if condition. I would have thought currentMax would end up being all the numbers > array[0], which in this case would be all the numbers > 1. Thanks in advance for any help.

______________________________________________________


func minMax(array: [Int]) -> (min: Int, max: Int) {

var currentMin = array[0]

var currentMax = array[0]

for value in array[1..<array.count] {

if value < currentMin {

currentMin = value

} else if value > currentMax {

currentMax = value

}

}

return (currentMin, currentMax)

}

let bounds = minMax(array: [1, 2, 3, 4, 5, 6, 7])

print("min is \(bounds.min) and max is \(bounds.max)")

// Prints "min is 1 and max is 7"
Answered by QuinceyMorris in 246055022

"currentMin" and "currentMax" are simple Int variables, not arrays, so the last assignment to each of them "wins".


BTW, you have a small bug in this code. If it is ever passed an empty array, your function will crash. You can avoid this by putting in a guard as the first line of your function:


     func minMax(array: [Int]) -> (min: Int, max: Int) {
          guard array.count > 0 else { return (0, 0) }
          …


However, returning min and max of 0 for an empty array may be a bug in itself, depending on what the calling code expects.


It's just one of those "edge cases" that you have to keep in mind when designing your code.

Accepted Answer

"currentMin" and "currentMax" are simple Int variables, not arrays, so the last assignment to each of them "wins".


BTW, you have a small bug in this code. If it is ever passed an empty array, your function will crash. You can avoid this by putting in a guard as the first line of your function:


     func minMax(array: [Int]) -> (min: Int, max: Int) {
          guard array.count > 0 else { return (0, 0) }
          …


However, returning min and max of 0 for an empty array may be a bug in itself, depending on what the calling code expects.


It's just one of those "edge cases" that you have to keep in mind when designing your code.

minMax func is intended to return the miminum and the maximum values in an array.


So it has to return only 2 numbers, the minimum and the maximum.


I'll try to answer each of your questions :


Why doesn't currentMax below get assigned every value in the array that is greater than its original value?

If it was doing so and comparing to the initial value, take the case where array is [1, 3, 2, 0]

here would be the successive values of currentMax with a test : if value > array[0]

- currentMax initialized with 1

we start to loop

- then for value = array[1] (the second item) : currentMax = 3, because 3 is greater than array[0] (1)

- then for value = array[2] (the third item) : currentMax = 2, because 2 is greater than array[0] (1)

it is no more the max of the array!

- and for value = array[3] (the fourth item) : currentMax remains 2, because 0 is smaller than array[0] (1)


So you need to test if the next value in array is greater than the currently found max : that's the purpose of comparing to currentMax: if value > currentMax

- currentMax initialized with 1

we start to loop

- then for value = array[1] (the second item) : currentMax = 3, because 3 is greater than currentMax (1)

- then for value = array[2] (the third item) : currentMax remains 3, because 2 is smaller than currentMax (3)

- and for value = array[3] (the fourth item) : currentMax remains 3, because 0 is smaller than currentMax (3)

At the end itwe have the max of the array!

How does it know to only assign the highest value that meets the else if condition.

Because currentMax is updated at each step in the loop, it the current max (hence its name) ; so if the tested number is not greater than him, it is ignored.

I would have thought currentMax would end up being all the numbers > array[0], which in this case would be all the numbers > 1

That would be a different function ; and it would have to return 2 arrays of Int, not 2 Ints


A last comment : you noticed that the loop is only for indices between 1..<array.count ; that is just to avoid a trivial test with array[0]

But you would get the same result with :


for value in array {
....
}

with an extra useless test on first item (number 0) in the array

Hope that's clear.

Thank you. I assumed it was grabbing the last one, but your label of "winning" it helps me understand. Also, the error is covered in the lesson in the next section on optional tuple return types.

For-in loop and why it stops
 
 
Q