进行数组转换的函数式编程方式

Functional programming way of doing array conversion

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
}

我正在 Swift 开发一个使用地图坐标的应用程序。我有一个 CLLocations 数组,我想从中创建一个距离和方位数组。上面的代码(为便于阅读而略微简化,因此可能不是 100% 正确)实现了这一点,但我想以更简洁的方式进行。这是可以用地图或过滤器完成的事情吗?仍在努力了解 FP 的做事方式。

这里是我想出的替代解决方案供参考:-

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()
    })
}

这使用了 Xcode 6.3 Beta 2 中的新 zip 方法,我将转换为 MapVector 的方法移到了 PointCalculator 结构中

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()
    }
}

并且此版本在 PointCalculator 结构上使用了相同的 toMapVector 方法,但使用了地图函数之外的变量,该变量由地图函数更新;这感觉不像 "correct"

这是相同问题的简化示例,但计算除外:

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

这里我计算数字的差和乘法。 请注意,这仅适用于 Swift 1.2 如果你需要它用于早期版本,你应该探索 Zip2.

的使用