Calling a property of a struct with a placeholder?

I have a few places in my app where I need to alter a property of a struct, but it takes a lot of code.

The struct, arrays and variables:
Code Block
struct Horse {
var name: String
    var basicTraining : Float
    var rhythm : Float
    var suppleness : Float
var myHorses = [
Horse(name: "Donnerhall", basicTraining : 0.5, rhythm : 0.2, suppleness : 0.1),
Horse(name: "Bjork", basicTraining : 0.4, rhythm : 0.3, suppleness : 0.1)
]
var horseIndex = 0
var scaleCode = [ basicSkills, rhythmSkills, supplenessSkills ]
var currentScaleCode = basicSkills
var skillIndex = 0


The current code (takes a lot of lines):
Code Block
func trainHorse() {
if myHorses[horseIndex].basicTraining > 100 {
                myHorses[horseIndex].basicTraining = 100 }
if myHorses[horseIndex].basicTraining < 100 {
                myHorses[horseIndex].basicTraining += currentScaleCode[skillIndex].basicBoost }
            
            if myHorses[horseIndex].rhythm > 100 {
                myHorses[horseIndex].rhythm = 100 }
            if myHorses[horseIndex].rhythm < 100 {
                myHorses[horseIndex].rhythm += currentScaleCode[skillIndex].rhythmBoost }
            if myHorses[horseIndex].suppleness > 100 {
                myHorses[horseIndex].suppleness = 100 }
            if myHorses[horseIndex].suppleness < 100 {
                myHorses[horseIndex].suppleness += currentScaleCode[skillIndex].supplenessBoost }
}


What I would like is to simplify this code by doing something like this:

Code Block
var currentTraining = basicTraining //or rhythm or suppleness
currentBoost = basicBoost
func trainHorse() {
if myHorses[horseIndex].currentTraining > 100 {
                myHorses[horseIndex].currentTraining = 100 }
if myHorses[horseIndex].currentTraining < 100 {
                myHorses[horseIndex].currentTraining += currentScaleCode[skillIndex].currentBoost }


But when I call a property using a placeholder, I get the error "Value of type 'Horse' has no member..." I have tried using different types of brackets and parentheses without luck
Answered by OOPer in 655049022
The word placeholder does not seem to be a good one to represent your issue.
Many languages have some feature to access properties indirectly, in Swift, it is called as keyPath.

But Swift is statically typed language and its usage is a little bit difficult:
Code Block
import Foundation
struct Horse {
var name: String
var basicTraining : Float
var rhythm : Float
var suppleness : Float
}
var myHorses = [
Horse(name: "Donnerhall", basicTraining : 0.5, rhythm : 0.2, suppleness : 0.1),
Horse(name: "Bjork", basicTraining : 0.4, rhythm : 0.3, suppleness : 0.1)
]
var horseIndex = 0
var currentTraining: WritableKeyPath<Horse, Float> = \.basicTraining //or \.rhythm or \.suppleness
func trainHorse() {
if myHorses[horseIndex][keyPath: currentTraining] > 100 {
myHorses[horseIndex][keyPath: currentTraining] = 100
}
if myHorses[horseIndex][keyPath: currentTraining] < 100 {
myHorses[horseIndex][keyPath: currentTraining] += currentScaleCode[skillIndex].basicBoost
}
//...
}


You are not showing relevant definitions in The struct, arrays and variables.
So, I do not see how to write currentBoost using keyPath.
I think I'll just call it on this one, it is working the way it is. In the future I can look up keypaths I can't make it work with if/switch statements. Thanks for the help though, sorry for wasting your time

sorry for wasting your time

I do not think I was wasting my time if you find a good solution. Just that we can save our (including you) time, if we could cooperate better.
Calling a property of a struct with a placeholder?
 
 
Q