Using Map to find Values in an Array

or, doing the absolute minimum

Prenez
VStackable

--

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!

--

--

Prenez
VStackable

Writes iOS apps in Swift and stories in American English.