Using Map to find Values in an Array
or, doing the absolute minimum
Just had the truly bizarre experience of someone giving me Kotlin on a Swift interview test, even though they clearly were clueless that that’s what they were doing.
I stared at the list of items they were showing me — I thought I was losing my mind. It was a Swift test but they’d handed me some syntax that I didn’t recognize…did I know nothing? Then, after the call ended, it dawned on me, they had given me Kotlin. In a Swift interview.
Anyway, once I had the ah-ha, I turned it into Swift tout suite.
import Foundation
struct MapPoint {
var latitude: Double
var longitude: Double
var timestamp: Int
}
struct Event {
var description: String
var timestamp: Int
}
var mapPoints: Array<MapPoint> = [
MapPoint(latitude: 0.0, longitude: 0.0, timestamp: 0),
MapPoint(latitude: 1.0, longitude: 0.0, timestamp: 10),
MapPoint(latitude: 2.0, longitude: 0.0, timestamp: 20),
MapPoint(latitude: 2.0, longitude: 1.0, timestamp: 30),
MapPoint(latitude: 2.0, longitude: 2.0, timestamp: 40),
MapPoint(latitude: 2.0, longitude: 3.0, timestamp: 50),
MapPoint(latitude: 2.5, longitude: 3.5, timestamp: 60),
MapPoint(latitude: 3.0, longitude: 4.0, timestamp: 70),
MapPoint(latitude: 3.0, longitude: 4.0, timestamp: 80),
MapPoint(latitude: 3.0, longitude: 4.0, timestamp: 90)
]
var events : Array<Event> = [
Event(description: "Distracted Driving", timestamp: 30),
Event(description: "Unsafe braking", timestamp: 68)
]
// this is what they gave me!
/*
mapPoints = listOf<MapPoint>
( MapPoint(latitude = 0.0, longitude = 0.0, timestamp = 0),
MapPoint(latitude = 1.0, longitude = 0.0, timestamp = 10),
MapPoint(latitude = 2.0, longitude = 0.0, timestamp = 20),
MapPoint(latitude = 2.0, longitude = 1.0, timestamp = 30),
MapPoint(latitude = 2.0, longitude = 2.0, timestamp = 40),
MapPoint(latitude = 2.0, longitude = 3.0, timestamp = 50),
MapPoint(latitude = 2.5, longitude = 3.5, timestamp = 60),
MapPoint(latitude = 3.0, longitude = 4.0, timestamp = 70),
MapPoint(latitude = 3.0, longitude = 4.0, timestamp = 80),
MapPoint(latitude = 3.0, longitude = 4.0, timestamp = 90) ),
//
//let events = listOf(
Event(description = "Distracted Driving", timestamp = 30),
Event(description = "Unsafe Braking", timestamp = 68)
//)
*/
So, the problem was, using the Timestamps in events, find the closest match in mapPoints.
The answer was obviously to use Map, do a test and return a Tuple of the event and the matching MapPoint. This answer depends on the MapPoints array being sorted, and settles for the greater of the two (in a case where not an exact match, as in the event where the timestamp is 68). Close enough for interview code.
func closePoints() {
let closestMapPoints = events.map { event -> (Event, MapPoint) in
let closestMapPoint = mapPoints.min {
abs($0.timestamp - event.timestamp)
< abs($1.timestamp - event.timestamp)
}
print (" \(event.timestamp), \(closestMapPoint?.timestamp ?? 999)")
return (event, closestMapPoint!)
}
There are other ways to do this, of course, and some depend on the size of the list for non-linear efficiency.
I contacted the recruiter afterwards to let them know I was cancelling the process and was no longer interested in the role. We crossed streams: they contacted the recruiter minutes later to let me know the same thing. Kismet!