Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

NAVEED CHOWDHURY
NAVEED CHOWDHURY
1,142 Points

Function that returns the maximum value from an array

How to write a function that returns the maximum value from a given array of integers, like a range of numbers? The user will input a number range.

1 Answer

Michael Hulet
Michael Hulet
47,912 Points

If it's a closed range, you can just use its upperBound. If it's a normal range, that'd be its upperBound - 1. If you have an Array of numbers, there's already a method for that, called max. For example(s):

let range = 1..<5
range.upperBound - 1 // This returns 4, which is the largest number in `range`

let closedRange = 1...5
range.upperBound // This returns 5, which is the largest number in `range`

let nums = [1, 3, 5, 4, 2]
nums.max() // This returns an optional 5, which is the largest number in `nums`, but you'll need to unwrap it
NAVEED CHOWDHURY
NAVEED CHOWDHURY
1,142 Points
func maxNumber(array: [Int]) ->(Int){
    var maxInt = array[0]
    for i in array[0..<array.count] {
        if array[i] >= maxInt {
            maxInt = array[i]

        }
    return maxInt
    }
}

// I was trying to hardcode the function but running into errors
Michael Hulet
Michael Hulet
47,912 Points

You have a few problems here.

First of all, your return is inside your loop, which may not run in all cases (if the array is empty, for example), so the Swift error will tell you that your function doesn't return an Int in all cases. Even if it wasn't a compiler error in Swift, it'd be returning after the first iteration in all cases, which isn't what you want here.You can move the return after the loop instead of inside it to remedy this.

Next, you're using i in the loop as if it's an index, but it's not. i contains the actual value and not the index of the value. This will lead to cases where your function will return the wrong answer, and often will crash. Instead of checking and assigning based on the number at the index i, you need to check and assign based on i itself.

The next problems aren't necessarily problems but they're stylistic issues that I feel you should address.

First of all, writing the return type of your function as (Int) made me think your function was going to return a tuple that contains a single unnamed Int member. In older versions of Swift, I suspect that it might. It'd be better to write it as just Int instead of (Int)

Next, there's no need to get a slice of array based on a range here, because you're always getting a slice of every member of array in this case. If you're going to do it like that, it'd be clearer/more efficient if you just iterated over array itself. However, for the sake of not doing work you don't have to, I'd actually iterate over a slice, but I'd start at index 1 so you don't have to check the first item against itself

Lastly, you should add checks to make sure that the array is empty in this case. If I pass an empty array to your function, it will crash on the first line with an index out of bounds error. In the case where the array is empty, I'd either return nil or throw an error

Altogether, this is how I'd implement this:

func maxNumber(array: [Int]) -> Int?{ // Note the lack of parentheses around the return type, and that we're returning an Optional
    guard array.count > 1 else{ // The algorithm I'm implementing needs the array to have more than 1 element
        return array.first // If it doesn't, we'll return the first item. This might be nil if the array is empty, which is what we want
    }

    var maxInt = array[0]
    for num in array[1..<array.count]{ // I renamed i to num for clarity. Also note that the loop starts at index 1
        if num > maxInt{ // I'm using a > instead of >= to skip an unnecessary copy/assignment if the numbers are equal
            maxInt = num
        }
    }
    return maxInt // Notice that the return is after the loop instead of inside it
}