0
struct MapVector {
    var distance: Double
    var bearing: Double
}

func distanceAndBearing() -> [MapVector] {
    var points = self.mapPoints
    var currPoint:CLLocation = points.first!
    points.removeAtIndex(0)

    var result: [MapVector] = []
    for point: CLLocation in points {
        let calc = PointCalculator(initialPoint: currPoint, nextPoint: point)

        let v = MapVector(distance: calc.pointDistance, bearing: calc.bearing)
        result.append(v)

        currPoint = point
    }

    return result
}

I am working in Swift on an application using map coordinates. I have a an array of CLLocations from which I would like to create an array of distances and bearings. The above code (its slightly simplified for readability, so may not be 100% correct) achieves that but I'd like to do it in a neater way. Is this something that can be done with map or filter? Still trying to get my head around the FP way of doing things.

2
  • is p supposed to be point in the line currPoint = p? Commented Feb 25, 2015 at 16:12
  • since you are using all the points in the array points to make your array of distances, I would say this is the way you would want to code it. If for some reason you were filtering out points then you would maybe want to use a filter. Commented Feb 25, 2015 at 16:59

2 Answers 2

1

Here is a simplified example for the same problem except the calculations:

let numbers = [3, 7, 2, 8, 3, 7, 5]
let result = numbers.isEmpty ? [] :
    map(zip(numbers, numbers[1..<numbers.count])) {
        (x, y) in
        return (diff: x - y, mult: x * y)
}

result[0].diff // -4
result[0].mult // 21

Here I compute the differences and the multiplications of the numbers. Note this will work only for Swift 1.2 In case you need it for earlier version, you should explore the use of Zip2.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks Matteo, this is exactly what I was looking for - concise and understandable, using the features of the language
0

For reference here are alternative solutions I came up with:-

func distanceAndBearing2() -> [MapVector]
{
    // make the removeAtIndex(0) part safe
    if (self.mapPoints.count == 0) {
        return []
    }

    var t2 = self.mapPoints
    t2.removeAtIndex(0)

    let t3 = zip(self.mapPoints, t2)

    return Array(t3).map({
        (p1, p2) in
        return PointCalculator(initialPoint: p1, nextPoint: p2).toMapVector()
    })
}

This uses the new zip method from Xcode 6.3 Beta 2, and I moved the conversion to MapVector into the PointCalculator struct

func distanceAndBearing3() -> [MapVector] {
    // make the shift part safe
    if (self.mapPoints.count == 0) {
        return []
    }

    var points = self.mapPoints
    var currPoint = points.shift()!

    return points.map {
        point in

        let initialPoint = currPoint
        currPoint = point

        return LocationPair(initialPoint: initialPoint,
            nextPoint: point).toMapVector()
    }
}

And this version uses the same toMapVector method on the PointCalculator struct, but uses a variable outside the map function which is updated by the map function; this feels like its not "correct"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.