Initialising a variable using another variable in a list

I am new to swift and creating a music theory app. To make it more readable, I would like the colour of each topic to change depending on the difficulty (ie 1 = green, 2 = orange, 3 = red). However, I cannot reference another variable (difficulty) when initialising the variable 'colour' using my function. I'm not sure how to fix this error: "cannot find 'difficulty' in scope" on lines 36-39. Thanks

Answered by Claude31 in 729133022

You cannot do that. But you don't need. colour is computed, so no need to pass as a parameter in Topic.

You can do this:

struct Topic: Identifiable {
    var id: UUID
    var name: String
    var difficulty: Int
    var colour: Color?
    
    init(id: UUID, name: String, difficulty: Int) {
        self.id = id
        self.name = name
        self.difficulty = difficulty
        self.colour = changeColour(difficulty: difficulty)
        
    func changeColour(difficulty: Int) -> Color {
        if difficulty == 1 {
                return .green
            } else if difficulty == 2 {
                return .orange
            } else {
                return .red
            }
          }
      }

}

var topics: [Topic] = [Topic(id: UUID(), name: "Major Scales", difficulty: 1),
                       Topic(id: UUID(), name: "Minor Scales", difficulty: 3),
                       Topic(id: UUID(), name: "Major Arpeggios", difficulty: 2),
                       Topic(id: UUID(), name: "Minor Arpeggios", difficulty: 3)]

print(topics[0].name, topics[0].colour!)
print(topics[1].name, topics[1].colour!)
print(topics[2].name, topics[2].colour!)
print(topics[3].name, topics[3].colour!)

You get:

Major Scales green
Minor Scales red
Major Arpeggios orange
Minor Arpeggios red

Note that changeColour may be defined inside init or outside:

struct Topic: Identifiable {
    var id: UUID
    var name: String
    var difficulty: Int
    var colour: Color?
    
    init(id: UUID, name: String, difficulty: Int) {
        self.id = id
        self.name = name
        self.difficulty = difficulty
        self.colour = changeColour(difficulty: difficulty)
    }
    
    func changeColour(difficulty: Int) -> Color {
        if difficulty == 1 {
            return .green
        } else if difficulty == 2 {
            return .orange
        } else {
            return .red
        }
    }
}
Accepted Answer

You cannot do that. But you don't need. colour is computed, so no need to pass as a parameter in Topic.

You can do this:

struct Topic: Identifiable {
    var id: UUID
    var name: String
    var difficulty: Int
    var colour: Color?
    
    init(id: UUID, name: String, difficulty: Int) {
        self.id = id
        self.name = name
        self.difficulty = difficulty
        self.colour = changeColour(difficulty: difficulty)
        
    func changeColour(difficulty: Int) -> Color {
        if difficulty == 1 {
                return .green
            } else if difficulty == 2 {
                return .orange
            } else {
                return .red
            }
          }
      }

}

var topics: [Topic] = [Topic(id: UUID(), name: "Major Scales", difficulty: 1),
                       Topic(id: UUID(), name: "Minor Scales", difficulty: 3),
                       Topic(id: UUID(), name: "Major Arpeggios", difficulty: 2),
                       Topic(id: UUID(), name: "Minor Arpeggios", difficulty: 3)]

print(topics[0].name, topics[0].colour!)
print(topics[1].name, topics[1].colour!)
print(topics[2].name, topics[2].colour!)
print(topics[3].name, topics[3].colour!)

You get:

Major Scales green
Minor Scales red
Major Arpeggios orange
Minor Arpeggios red

Note that changeColour may be defined inside init or outside:

struct Topic: Identifiable {
    var id: UUID
    var name: String
    var difficulty: Int
    var colour: Color?
    
    init(id: UUID, name: String, difficulty: Int) {
        self.id = id
        self.name = name
        self.difficulty = difficulty
        self.colour = changeColour(difficulty: difficulty)
    }
    
    func changeColour(difficulty: Int) -> Color {
        if difficulty == 1 {
            return .green
        } else if difficulty == 2 {
            return .orange
        } else {
            return .red
        }
    }
}
Initialising a variable using another variable in a list
 
 
Q