Swift Keypaths

Extending Sequence to have method that calculates sum:

extension Sequence where Element: AdditiveArithmetic {
    func sum() -> Element { reduce(.zero, +) }
}

This sum() available for any sequence with values that confirms AdditiveArithmetic protocol.

Consider we have custom struct like and array of this objects:

struct LocationData {
    let speed: Double
}

let data = [10, 11, 14, 15, 19].map(LocationData.init)

To calculate average speed we find sum and divide by count:

let avgSpeed = data.map { $0.speed }.sum() / Double(data.count)
// avgSpeed = 13.8

Using keypath we can reference to properties:

let speedKeyPath = \LocationData.speed

Let’s extend sequence to have method that calculates sum of given keypath element:

extension Sequence {
    func sum<T: AdditiveArithmetic>(by keyPath: KeyPath<Element, T>) -> T {
        map { $0[keyPath: keyPath] }.sum()
    }
}

Now average speed calculation can be expressed shorter:

let avgSpeed = data.sum(by: \.speed) / Double(data.count)
// avgSpeed = 13.8