I have an app with an array of models that contain number fields. I’d like to be
able to sum any given data field. I can do so with map by using the data field
name ($0.cups for example). However I would like to programmatically send in a
variable for "cups" and nothing I have tried works.
Here’s some example code. I’d like to pass the field name that I want to total into
the function sumOnAttribute
struct ContentView: View {
@State private var answer: String = ""
@State private var startingModels = [
StartingModel(name: "abe", age: 1, bags: 2, cups: 3),
StartingModel(name: "abe", age: 11, bags: 12, cups: 13),
StartingModel(name: "abe", age: 21, bags: 22, cups: 23),
StartingModel(name: "donna", age: 31, bags: 32, cups: 33),
StartingModel(name: "elsie", age: 41, bags: 42, cups: 43),
StartingModel(name: "farah", age: 51, bags: 52, cups: 53)
]//some data
var body: some View {
VStack(spacing: 10) {
Text("Do Some Math")
.font(.title)
Text(answer)
.font(.headline)
Button {
answer = String(sumOnAttribute(filterField: "abe", sumField: "cups"))
} label: {
Text("Make it So")
}
.font(.system(size: 20))
}//v
}//body
func sumOnAttribute(filterField: String, sumField: String) -> Double {
let filteredAttribute = startingModels.filter({ $0.name == filterField })
//$0.sumField does not work, $0.value(sumField) does not work
let nums = filteredAttribute.map({ $0.cups })
let total = nums.reduce(0, +)
return total
}
}//struct
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct StartingModel: Identifiable {
let id = UUID()
let name: String
let age: Double
let bags: Double
let cups: Double
}//model
Seems like this should be simple, but I have not found any answer in a lot of searches.
Any guidance would be appreciated. Xcode 13.3, iOS 15.4
2
Answers
One option is a
KeyPath
— it’s not aString
like you’re using, but rather a compile-time-safe path to the property you’re looking for. An implementation might look like this:If you really wanted to use a
String
, you could consider using@dynamicMemberLookup
: https://www.hackingwithswift.com/articles/55/how-to-use-dynamic-member-lookup-in-swiftnot clear what you want, maybe you could try something like this, "…to pass the field name that I want to total into the function sumOnAttribute…":