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 Swift 2.0 Functions Function Parameters Returning Complex Values

Hi is there anybody who is familiar with solving the function problem that can can help me please ?

For this challenge, let's say we're building a component of an app that allows a user to type in a location of a famous landmark and get back the geographical coordinates.

To keep the scope limited, let's say we're only working with the following values.

Eiffel Tower - lat: 48.8582, lon: 2.2945 Great Pyramid - lat: 29.9792, lon: 31.1344 Sydney Opera House - lat: 33.8587, lon: 151.2140

Declare a function named getTowerCoordinates that takes a single parameter of type String, named location, and returns a tuple containing two Double values (Note: You do not have to name the return values)

Use a switch statement to switch on the string passed in to return the right set of coordinate values for the location.

For example, if I use your function and pass in the string "Eiffel Tower" as an argument, I should get (48.8582, 2.2945) as the value.

func getTowerCoordinates(namedloction: String = "Eiffel Tower" )-> (Double, Double){

    switch namedloction {
        case "Eiffel Tower": break
        case "Great Pyramid": break
        case "Sydney Opera House": break
        default: (48.8582,2.2945); break

}

return(48.8582,2.2945)

}

6 Answers

Matthew Young
Matthew Young
5,133 Points

Some things to point out with your code: (1.) The challenge terms state that the inputted variable should be named as "location", and you've named it "namedloction". (2.) You've hardcoded an input value for your function, which you shouldn't do. (3.) Your switch statement is effectively breaking out of the statement for each case without really executing any code.

I think you've confused the example they've presented as the task for the challenge. They're just saying that if, for example, the user inputs "Eiffel Tower" as the location name, the function should return the tuple (48.8582, 2.2945).

This should be the correct code:

func getTowerCoordinates(location: String) -> (Double,Double) {
    switch location {
        case "Eiffel Tower": return (48.8582, 2.2945)
        case "Great Pyramid": return (29.9792, 31.1344)
        case "Sydney Opera House": return (33.8587, 151.2140)
        default: return (0,0)
    }
}

With switch statements, you're taking a variable and comparing the value against multiple cases within the closure. If the value matches up with a specific case, the code following that case is executed and the application breaks out of that switch statement. If the value doesn't match up with a specific case, the default case's code is executed and the application breaks out of that switch statement.

It work and I differently see my mistakes now and will go back and practice more, Thanks for your help Matthew!

Hi, this was my solution and it was accepted after submitting:

func getTowerCoordinates(location: String) -> (Double, Double) {

    var lat: Double = 0.0, lon: Double = 0.0

    switch location {
    case "Eiffel Tower": lat = 48.8582; lon = 2.2945
    case "Great Pyramid": lat = 29.9792; lon = 31.1344
    case "Sydney Opera House": lat = 33.8587;  lon = 151.2140
    default: return (0,0)
    }

return (lat, lon)
}
Rich Braymiller
Rich Braymiller
7,119 Points

ahhh I forgot to use the word return by default, otherwise, I did the exact same as you.

Morten Larsen
Morten Larsen
12,275 Points

Hi guys,

Im not exactly getting why we need to use a tuple (double, double)? Maybe someone can help me out understandig.

Do we use a tuple whenever we want to return something?

And how does the tuple knows which things to return? Does the tuple knows it because we use the keyword "return"?

Matthew Young
Matthew Young
5,133 Points

We need to return the latitude and longitude value of a particular location. In Swift, to return two separate values of a function we need to use a tuple. We don't have to use a tuple if we only need one value returned.

In our declaration of the function, we specified that this function is returning a tuple consisting of two Doubles:

-> (Double, Double)

Therefore, in our return statement, the function is expecting to return only a tuple consisting of two Double values. If we didn't return exactly that, we would get an error.

To recall the value of that tuple, we just have to use dot notation after the variable name that stores the returned value (similar to accessing an instance's class/struct properties). In the code I typed up, you would use .0 and .1 to access the latitude and longitude properties, respectively. Like so:

let coordinates = getTowerCoordinates("Eiffel Tower")

print(coordinates.0) //Prints out "48.8582"
print(coordinates.1) //Prints out "2.2945"

While the code I posted in my initial response functionally works and completes the challenge, it would be better to name those tuple values to better understand what those values represent. In that case, I would change the function declaration to this:

func getTowerCoordinates(location: String) -> (latitude: Double, longitude: Double)

Then, I can access the tuple's values by doing this:

let coordinates = getTowerCoordinates("Eiffel Tower")

print(coordinates.latitude) //Prints out "48.8582"
print(coordinates.longitude) //Prints out "2.2945"

Source: Functions "Functions with Multiple Return Values" and The Basics "Tuples"

Morten Larsen
Morten Larsen
12,275 Points

Thank you very much! Helped me so much!

Juan Bosco
Juan Bosco
5,843 Points

As an extra bonus step, how could I print something like "The value you entered does not exist" instead of (0,0)? I have been trying myself with the docs and the internet and can't make it. Thanks!

Matthew Young
Matthew Young
5,133 Points

Given the current function declaration, our return type is a tuple consisting of two Double values. Therefore, we have to return a tuple consisting of two Double values. We always have to return whatever we declare as the return type in our function.

However, we can make the return type an OPTIONAL tuple instead by placing a '?' after the tuple in our function declaration. By doing this, we can return nil for the default clause in our switch statement instead of a value. The function would look like this:

func getTowerCoordinates(location: String) -> (latitude: Double, longitude: Double)? {
    switch location {
        case "Eiffel Tower": return (48.8582, 2.2945)
        case "Great Pyramid": return (29.9792, 31.1344)
        case "Sydney Opera House": return (33.8587, 151.2140)
        default: return nil
    }
}

When we make the function call, we can check if the function returns a value or nil. If the function returns nil, we can print out the statement "The value you entered does not exist". An example of this function call would be as follows:

if let coordinates = getTowerCoordinates("Tower of Terror") { 
     //If we get a coordinate tuple response, we handle that response in here...
} else {
     //If we get nil as a response...
     print("The value you entered does not exist")
}

For a more advanced concept, we could throw an error. I would say it's excessive for this scenario, but is useful for functions that could have multiple reasons why a valid value could not be returned. I'll include a link about it below.

Related Information:

The Swift Programming Language - The Basics - Optionals

The Swift Programming Language - Error Handling

func coordinates(for location: String) -> (Double, Double) {

switch location {
case "Eiffel Tower": return (48.8582, 2.2945)
case "Great Pyramid": return (29.9792, 31.1344)
case "Sydney Opera House": return (33.8587, 151.2140)
default: return (0,0)
}

} coordinates(for : "Eiffel Tower")