MH175
MH175

Reputation: 2334

Test if enum is part of a set - with high performance

I will be receiving many rapid status codes from a network. The status code will be used to initialize an enum by matching it against its rawValue:

enum Animal: Int {

    case cockerSpaniel = 10 //dog
    case labrador = 20 //dog
    case beagle = 30 //dog

    case hamster = 40 //rodent
    case rat = 50 //rodent
    case mouse = 60 //rodent

}

But sometimes I need to ignore the status code if the rawValue isn't part of a particular group:

enum AnimalType {
    case dog //all the rawValues associated with dogs
    case rodent //all the rawValues associated with rodents
}

Is there some performant mechanism whereby I can group related enums and test if the enum created from a rawValue matches a group?

Of course I could always do this with a dictionary or array:

let dogs: [Int: Animal] = {
     var dict = [Int : Animal]()
     dict[Animal.cockerSpaniel.rawValue] = Animal.cockerSpaniel
     dict[Animal.labrador.rawValue] = Animal.labrador
     dict[Animal.beagle.rawValue] = Animal.beagle
     return dict
}()

But then I lose the type checking of having an actual enum for the set of dogs.

Upvotes: 3

Views: 431

Answers (1)

Alexander
Alexander

Reputation: 63397

Here's what I would do, if I understand the question correctly:

enum Animal: Int {
    case cockerSpaniel = 10 //dog
    case labrador = 20 //dog
    case beagle = 30 //dog

    case hamster = 40 //rodent
    case rat = 50 //rodent
    case mouse = 60 //rodent

    enum AnimalGroup {
        case dog
        case rodent
    }

    var group: AnimalGroup {
        switch self {
            case .cockerSpaniel, .labrador, .beagle: return .dog
            case .hamster, .rat, .mouse: return .rodent
        }
    }
}

let statusCode = 10

 guard let animal = Animal(rawValue: statusCode) else {
    fatalError("Invalid status code")
}


if animal.group == .dog {
    print("\(animal) is a dog.")
}

Upvotes: 7

Related Questions