Reputation: 65
At the moment I'm working with enums where I need in some object store different enum cases but I want to avoid doing switch statement in every implementation. In my custom object Im saving his type from enum "CarModType" where I have specified more subTypes as "Engine, Interior, Exterior...". So I can store in my object that this current object is type "Interior.Seats" and I don't need work with my "type" variability which is var type: PostProcessingFramework.CarModType?
in order to store different enums for CarModType e.g "Engine, Exterior, Interior". My enums seems like this:
public enum CarModType {
case interior(Interior)
case exterior(Exterior)
case engine(Engine)
case driveTrain(DriveTrain)
case suspension(Suspension)
case steering(Steering)
case brakes(Brakes)
case extra(Extra)
enum Interior: String,CaseIterable {
case steering = "interior.steering"
case seats = "interior.seats"
case shiftSystem = "interior.shiftSystem"
case pedals = "interior.pedals"
case accessories = "interior.accessories"
case centralUnit = "interior.centralUnit"
case extra = "interior.extra"
class stored {
static let array:[PostProcessingFramework.CarModType.Interior] = [.accessories,.centralUnit,.extra,.pedals,.seats,.shiftSystem,.steering]
}
static func returnTitle(category: PostProcessingFramework.CarModType.Interior) -> String {
switch category {
case .steering:
return "Steering"
case .seats:
return "Seats"
case .shiftSystem:
return "Shift System"
case .pedals:
return "Pedals"
case .accessories:
return "Accessories"
case .centralUnit:
return "Central Unit"
case .extra:
return "Extra"
}
}
}
Then I was facing other problem, because of my DB I'm saving this type in his rawValue as I have specified in subTypes. Cuz of that, I came up with some functions which will transform all enum cases into an dictionary and then I can by accessing this dictionary with key as rawValue of nested Enum (subType) get a specific "Type" (e.g CarModType.Engine(.cylinderHead)) from rawValue. My functions:
static func returnType(rawValue: String) -> CarModType? {
let semaphore = DispatchSemaphore(value: 0)
let dictionaries = [
Dictionary(uniqueKeysWithValues: CarModType.Interior.allCases.map{ (CarModType.interior($0).stringValue,CarModType.interior($0)) }),
Dictionary(uniqueKeysWithValues: CarModType.Exterior.allCases.map{ (CarModType.exterior($0).stringValue,CarModType.exterior($0)) }),
Dictionary(uniqueKeysWithValues: CarModType.Engine.allCases.map{ (CarModType.engine($0).stringValue,CarModType.engine($0)) })
]
var dict = [String:CarModType]()
var i = 0
for subDict in dictionaries {
dict.merge(subDict){(_, curr) in curr }
i += 1
if i == dictionaries.count {
semaphore.signal()
}
}
semaphore.wait()
if let val = dict[rawValue] {
return val
} else {
return nil
}
}
var stringValue: String {
switch self {
case let .interior(subtype):
if let type = PostProcessingFramework.CarModType.Interior.init(rawValue: subtype.rawValue) {
return type.rawValue
} else {
return ""
}
case let .exterior(subtype):
if let type = PostProcessingFramework.CarModType.Exterior.init(rawValue: subtype.rawValue) {
return type.rawValue
} else {
return ""
}
case let .engine(subtype):
if let type = PostProcessingFramework.CarModType.Engine.init(rawValue: subtype.rawValue) {
return type.rawValue
} else {
return ""
}
}
}
Isn't out there some better, more "elegant" way to have done this ? Thank you very much for answers !
Upvotes: 0
Views: 721
Reputation: 52088
Assuming all raw values are unique, like they seem to be for Interior
with the namespace like string, you can add an init
at the top level that goes through and tries to create an instance of each sub type until it succeeds
Here is an example for the 2 first case elements
init?(asRaw: String) {
if let item = Interior(rawValue: asRaw) {
self = CarModType.interior(item)
} else if let item = Exterior(rawValue: asRaw) {
self = CarModType.exterior(item)
//... rest of case items here
} else {
return nil
}
}
Upvotes: 1