Modifying an associated value of an existing enum instance

Hi, I would like to modify an associated value of an existing enum instance of the the following enum:

enum FilterItem: Equatable, Hashable {
        case work(isSelected: Bool)
        ...

        var filterName: String {
            switch self {
                case .work: return "Work"
                ... 
             }
         }

        var isSelected: Bool {
            switch self {
                case .work(let isSelected): return isSelected
                ... 
             } 
          }

I want to be able to switch on the FilterItem type and then to be able to modify the isSelected property of the instance like:

let itemToChange: FilterItem
        switch item {
            case .work(let isSelected):
                itemToChange.isSelected = !isSelected

I know the above code doesn't compile, but I was wondering if there was a way I could modify my enum instance without creating a totally new enum instance.

Answered by AJabero in 848420022

This is not possible, and to resolve this I am going to change the FilterItem into a struct.

This is not possible, and to resolve this I am going to change the FilterItem into a struct.

Right. You can’t change associated values in an enum, you have to change the enum itself. And if the enum is a let constant, like itemToChange in your example, you can’t replace the value with your new enum.

without creating a totally new enum instance.

Keep in mind that enums are highly optimisable, and thus creating a “totally new enum instance” isn’t a significant runtime cost. So you only really care about what your code looks like, and there are various tricks you can play there.

It’s hard to offer concrete advice without seeing the other cases in your FilterItem. If you care to share more details about that enum, I’d be happy to dig into this further.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you @DTS Engineer , this is what the rest of the enum cases, and its computed properties, look like:


enum FilterItem: Hashable {
        case work(isSelected: Bool)
        case family(isSelected: Bool)
        case health(isSelected: Bool)
        case social(isSelected: Bool)
        case energetic(isSelected: Bool)
        case tired(isSelected: Bool)
        case restless(isSelected: Bool)
        case heavy(isSelected: Bool)
        case numb(isSelected: Bool)
        case calm(isSelected: Bool)
        case tense(isSelected: Bool)
        case light(isSelected: Bool)
        case racing(isSelected: Bool)
        case focused(isSelected: Bool)
        case confused(isSelected: Bool)
        case overthinking(isSelected: Bool)
        case blank(isSelected: Bool)
        case reflective(isSelected: Bool)
        case head(isSelected: Bool)
        case neck(isSelected: Bool)
        case chest(isSelected: Bool)
        case shoulders(isSelected: Bool)
        case arms(isSelected: Bool)
        case solarPlexus(isSelected: Bool)
        case stomach(isSelected: Bool)
        case lowerAbdomen(isSelected: Bool)
        case legs(isSelected: Bool)
        case wholeBody(isSelected: Bool)
        
        var filterName: String {
            switch self {
                case .work: return "Work"
                case .family: return "Family/Relationships"
                case .health: return "Health/Physical Wellbeing"
                case .social: return "Social"
                case .energetic: return "Energetic/Alert"
                case .tired: return "Tired/Fatigued"
                case .restless: return "Restless/Fidgety"
                case .heavy: return "Heavy/Weighted Down"
                case .numb: return "Numb/Tingling"
                case .calm: return "Calm/Relaxed"
                case .tense: return "Tense/Tight"
                case .light: return "Light/Buzzing"
                case .racing: return "Racing/Fast"
                case .focused: return "Focused/Clear"
                case .confused: return "Confused/Foggy"
                case .overthinking: return "Overthinking/Spiralling"
                case .blank: return "Blank"
                case .reflective: return "Reflective/Meditative"
                case .head: return "Head"
                case .neck: return "Neck/Throat"
                case .chest: return "Chest/Heart"
                case .shoulders: return "Shoulders"
                case .arms: return "Arms/Hands"
                case .solarPlexus: return "Solar Plexus"
                case .stomach: return "Stomach/Gut"
                case .lowerAbdomen: return "Lower Abdomen/Core"
                case .legs: return "Legs/Feet"
                case .wholeBody: return "Whole Body"
            }
        }
        
        var category: EmotionFiltersViewController.Section {
            switch self {
                case .work: return .lifeEvents
                case .family: return .lifeEvents
                case .health: return .lifeEvents
                case .social: return .lifeEvents
                    
                case .energetic: return .physicalSensations
                case .tired: return .physicalSensations
                case .restless: return .physicalSensations
                case .heavy: return .physicalSensations
                case .calm: return .physicalSensations
                case .tense: return .physicalSensations
                case .light: return .physicalSensations
                case .numb: return .physicalSensations
                    
                case .racing: return .mindThoughts
                case .focused: return .mindThoughts
                case .confused: return .mindThoughts
                case .overthinking: return .mindThoughts
                case .blank: return .mindThoughts
                case .reflective: return .mindThoughts
                    
                case .head: return .bodyLocation
                case .neck: return .bodyLocation
                case .chest: return .bodyLocation
                case .shoulders: return .bodyLocation
                case .arms: return .bodyLocation
                case .solarPlexus: return .bodyLocation
                case .stomach: return .bodyLocation
                case .lowerAbdomen: return .bodyLocation
                case .legs: return .bodyLocation
                case .wholeBody: return .bodyLocation
            }
        }
        
        var isSelected: Bool {
            switch self {
                case .work(let isSelected): return isSelected
                case .family(let isSelected): return isSelected
                case .health(let isSelected): return isSelected
                case .social(let isSelected): return isSelected
                    
                case .energetic(let isSelected):
                    return isSelected
                case .tired(let isSelected):
                    return isSelected
                case .restless(let isSelected):
                    return isSelected
                case .heavy(let isSelected):
                    return isSelected
                case .calm(let isSelected):
                    return isSelected
                case .tense(let isSelected):
                    return isSelected
                case .light(let isSelected):
                    return isSelected
                case .numb(let isSelected):
                    return isSelected
                    
                case .racing(let isSelected):
                    return isSelected
                case .focused(let isSelected):
                    return isSelected
                case .confused(let isSelected):
                    return isSelected
                case .overthinking(let isSelected):
                    return isSelected
                case .blank(let isSelected):
                    return isSelected
                case .reflective(let isSelected):
                    return isSelected
                    
                case .head(let isSelected):
                    return isSelected
                case .neck(let isSelected):
                    return isSelected
                case .chest(let isSelected):
                    return isSelected
                case .shoulders(let isSelected):
                    return isSelected
                case .arms(let isSelected):
                    return isSelected
                case .solarPlexus(let isSelected):
                    return isSelected
                case .stomach(let isSelected):
                    return isSelected
                case .lowerAbdomen(let isSelected):
                    return isSelected
                case .legs(let isSelected): return isSelected
                case .wholeBody(let isSelected): return isSelected
            }
        }
    }
Accepted Answer

Thanks for posting more details.

I usually solve this problem by creating an outer struct with the common properties. For example:

struct FilterItem {
    var isSelected: Bool
    var kind: FilterItemKind
}

enum FilterItemKind {
    case work
    case family
    … and so on …
}

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you, this is the approach that I've implemented in my code.

Modifying an associated value of an existing enum instance
 
 
Q