Home > Back-end >  SwiftUI Can't Pass String to KeyPath
SwiftUI Can't Pass String to KeyPath

Time:04-22

I have an app that references a large dataset that I load from an external public site as a comma separated value file. I parse the data to a an array of a model called WaterPointModel. An abbreviated version is:

struct WaterPointModel: Identifiable {

    let id = UUID()

    let STATE: String
    let COUNTY: String
    let AQWFrTo: Double
    let AQWGWSa: Double
    let AQWGWTo: Double
    //many more
}

I then want to summarize(reduce) the data. My function for this is:

func sumOnAttributeUSList(sumField: KeyPath<WaterPointModel,Double>) -> Double {
    return dataStore.waterPointModels.map({ $0[keyPath:sumField] }).reduce(0,  )
}

Next I want to call this to build a report:

let aqWFrTo = sumOnAttributeUSList(sumField: \.AQWFrTo)    

This all works. However there are other reports where I need to pass a string to create that keypath. Say I have a lookup table where I lookup "abc" and get "AQWFrTo". I would like to do something like this in a loop:

let abc = "AQWFrTo"
let aqWFrTo = sumOnAttributeUSList(sumField: \WaterPointModel.abc)

I have not been able to make any version of this work. Any guidance would be appreciated.

Xcode 13.3.1, iOS 15.4

CodePudding user response:

A simple approach is this:

func toKeypath(_ str: String) -> KeyPath<WaterPointModel,Double>? {  // <-- with or without optional
    switch str {
        case "AQWFrTo": return \.AQWFrTo
        case "AQWGWSa": return \.AQWGWSa
        case "AQWGWTo": return \.AQWGWTo
        // ...
        default: return nil  // <-- or a default Keypath
    }
}

let aqWFrTo = sumOnAttributeUSList(sumField: toKeypath("AQWFrTo"))
  • Related