Le Mot Juiced Le Mot Juiced - 4 months ago 18
Swift Question

Best way to nest enums for access by switch statements in Swift?

I have a nested enum like so, for describing basic relative positioning:

enum Location {
enum Top {
case Left
case Right
case Center
}
enum Bottom {
case Left
case Right
case Center
}
enum Left {
case Top
case Bottom
case Center
}
enum Right {
case Top
case Bottom
case Center
}
enum Center {
case Center
}
}


If I try to run a
switch
statement with it, none of the enums show up as possible cases, and if I try to list them I get an error:

func switchOverEnum(enumCase: Location) {
switch enumCase {
case .Top:
print("hey this didn't cause an error whoops no it did")
}
}


The error is:
Enum case 'Top' not found in type 'Location'.


Now there's a version of this question here, and according to the most helpful answer, it should be done like this:

enum Location {
enum TopLocations {
case Left
case Right
case Center
}
enum BottomLocations {
case Left
case Right
case Center
}
enum LeftLocations {
case Top
case Bottom
case Center
}
enum RightLocations {
case Top
case Bottom
case Center
}
enum CenterLocations {
case Top
case Bottom
case Left
case Right
case Center
}
case Top(TopLocations)
case Bottom(BottomLocations)
case Left(LeftLocations)
case Right(RightLocations)
case Center(CenterLocations)
}


Which totally works, but seems a bit clunky, or inelegant, or un-Swift-like. Is this really the best way?

Answer

I think this would be much more concisely expressed with two enums and a tuple. Try this in a playground:

enum HorizontalPosition {
    case Left
    case Right
    case Center
}

enum VerticalPosition {
    case Top
    case Bottom
    case Center
}

typealias Location = (horizontal: HorizontalPosition, vertical: VerticalPosition)

let aLocation = Location(horizontal: .Left, vertical: .Bottom)

switch aLocation {

case (.Left, .Bottom): print ("left bottom")
case (.Center, .Center): print ("center center")
default: print ("everything else")
}
Comments