This article is part of a series on learning Swift by writing code to The Swift Programming Language book from Apple.
We've covered the basics up to functions, and reviewed them in the last article, and we're going to continue reviewing those chapters in this one.
Set up a reading environment
If you are jumping around these articles, make sure you read the Introduction to see my recommendation for setting up a reading environment.
Exercises
For this chapter, we're going to write code inspired by the Maps app.
Copy this into your playground
let places: [[String: Any]] = [
["name": "Buckingham Palace", "location": (lat: 51.5000632, long: -0.1449567)],
["name": "Great Pyramid of Giza", "location": (lat: 29.9792391, long: 31.1320079)],
["name": "Sydney Opera House", "location": (lat: -33.8567799, long: 151.2131027)],
["name": "Machu Picchu", "location": (lat: -13.163136, long: -72.5471569)],
["name": "Victoria Falls", "location": (lat: -17.9149133, long: 25.8379429)],
["name": "Empire State Building", "location": (lat: 40.7484445, long: -73.9878584)],
["name": "The Forbidden City", "location": (lat: 39.9394501, long: 116.1152174)],
["name": "Parthenon", "location": (lat: 38.3336346, long: 20.9712001)],
]
To make sure you understand how to access data in this structure, start with this code:
let name = places[0]["name"] as? String
let location = places[0]["location"] as? (lat: Double, long: Double)
location?.lat
In your Playground write code to do the following
- Print out the longitude (
.long
) of The Sydney Opera House. - Use this page to find the distance between two of these places by plugging in their latitudes and longitudes.
- Implement the Haversine distance formula. If you are an experienced programmer (just new to Swift), then read the Javascript version on that page and try to port it.
- Once you have that, write a function that takes the
places
data and returns the two places that are closest to each other. (In Swift, the basic math functions are all global functions:sin
,cos
,atan2
,pow
, etc)
More help for beginners
Ok, step one is to declare a function that takes two lat/long tuples and returns a Double
.
Start with this:
let location1 = places[0]["location"] as? (lat: Double, long:Double)
let location2 = places[1]["location"] as? (lat: Double, long:Double)
func distanceKm(loc1: (lat: Double, long: Double)?, loc2: (lat: Double, long: Double)?)
-> Double? {
if let loc1 = loc1, let loc2 = loc2 {
// Implement Haversine here
return 0 // .. replace this line
}
return 0
}
distanceKm(loc1: location1, loc2: location2)
Here is the basic algorithm:
- Declare a constant
R
which is 6371000.0 (the radius of the Earth) - Declare a constant
phi1
which isloc1.lat
in radians:loc1.lat * .pi / 180.0
(in general:radians = degrees * .pi / 180.0
) - Declare a constant
phi2
which isloc2.lat
in radians - Declare a constant
deltaPhi
which is(loc2.lat - loc1.lat)
in radians - Declare a constant
deltaLambda
which is(loc2.long - loc1.long)
in radians - Declare a constant
a
to bepow(sin(deltaPhi / 2), 2) + cos(phi1) * cos(phi2) * pow(sin(deltaLambda/2), 2)
- Declare a constant
c
to be2 * atan2(sqrt(a), sqrt(1-a))
- Return
R * c / 1000.0
distanceKm(loc1: location1, loc2: location2)
should be around 3511
just like the web page.
Now see if you can find the two closest places. Start with this
func closestTo(places: [[String: Any]], loc: (lat: Double, long: Double)) -> String {
var smallestDistance = Double.greatestFiniteMagnitude
var closest = ""
for p in places {
if
let name = p["name"] as? String,
let loc2 = p["location"] as? (lat: Double, long: Double),
let distance = distanceKm(loc1: loc, loc2: loc2),
distance < smallestDistance {
smallestDistance = distance
closest = name
}
}
return closest
}
// Find the closest place to the Eiffel Tower (should be Buckingham Palace)
closestTo(places: places, loc: (lat: 48.8583736, long: 2.2922873))
Use this function as a start. You need to make sure you don't compare a place to itself, because that will always be the closest.
DM me or comment below if you need help.
Next: Closures
The next article will provide exercises for the Closures chapter. Read it before you move on.
Top comments (0)