Swift 4中的嵌套枚举

Swift 4中的嵌套枚举,swift,enums,Swift,Enums,当前从长嵌套枚举中提取数据的实现似乎相当繁琐,维护此类结构也很费劲。下面是一个实现示例,我只是想了解一下这是否是从这些枚举中提取数据的正确方法 import UIKit import Foundation enum HousingType { case House(HousingSubType) case Apartment(HousingSubType) case Mansion(HousingSubType) enum HousingSubType: Ca

当前从长嵌套枚举中提取数据的实现似乎相当繁琐,维护此类结构也很费劲。下面是一个实现示例,我只是想了解一下这是否是从这些枚举中提取数据的正确方法

import UIKit
import Foundation

enum HousingType {
    case House(HousingSubType)
    case Apartment(HousingSubType)
    case Mansion(HousingSubType)

    enum HousingSubType: CaseIterable {
        case Victorian
        case Modern
        case Standard
    }

    var name: String {
        switch self {
        case let .House(subtype):
            switch subtype {
            case .Modern:
                return Structure.House.Modern.name
            case .Standard:
                return Structure.House.Standard.name
            case .Victorian:
                return Structure.House.Victorian.name
            }
        case let .Apartment(subtype):
            switch subtype {
            case .Modern:
                return Structure.Apartment.Modern.name
            case .Standard:
                return Structure.Apartment.Standard.name
            case .Victorian:
                return Structure.Apartment.Victorian.name
            }
        case let .Mansion(subtype):
            switch subtype {
            case .Modern:
                return Structure.Mansion.Modern.name
            case .Standard:
                return Structure.Mansion.Standard.name
            case .Victorian:
                return Structure.Mansion.Victorian.name
            }
        }
    }

    static var allCases: [HousingType] {
        return
            HousingType.HousingSubType.allCases.map(HousingType.House)
                + HousingType.HousingSubType.allCases.map(HousingType.Apartment)
                + HousingType.HousingSubType.allCases.map(HousingType.Mansion)
    }
}

enum Structure {
    enum House {
        enum Victorian {
            static let name = "Victorian House"
            static let rooms = 4
            static let bathrooms = 1
        }
        enum Modern {
            static let name = "Modern House"
            static let rooms = 4
            static let bathrooms = 4
        }
        enum Standard {
            static let name = "Standard House"
            static let rooms = 4
            static let bathrooms = 2
        }
    }

    enum Apartment {
        enum Victorian {
            static let name = "Victorian Apartment"
            static let rooms = 2
            static let bathrooms = 1
        }
        enum Modern {
            static let name = "Modern Apartment"
            static let rooms = 2
            static let bathrooms = 2
        }
        enum Standard {
            static let name = "Standard Apartment"
            static let rooms = 2
            static let bathrooms = 1
        }
    }

    enum Mansion {
        enum Victorian {
            static let name = "Victorian Mansion"
            static let rooms = 10
            static let bathrooms = 3
        }
        enum Modern {
            static let name = "Modern Mansion"
            static let rooms = 10
            static let bathrooms = 10
        }
        enum Standard {
            static let name = "Standard Mansion"
            static let rooms = 10
            static let bathrooms = 6
        }
    }
}
输出用于:

for type in HousingType.allCases {
    print(type.name)
}
是:

和输出

let apartment = HousingType.Apartment(.Modern)
print(apartment.name)
是:

我可以很容易地从枚举中获取数据并遍历所有情况,但正如您所看到的,对于单个变量
name
,遍历每个可能的情况需要大量的代码。当我添加代码以获取
房间
浴室
或添加额外的
住房子类型
时,此实现的长度变得非常长


有没有更好的方法来获取变量
name
,而不必通过一系列switch语句显式写出每个可能的情况?当我试图拥有一系列不同类型、子类型、子类型等的静态变量时,是否有一个完全不同的实现我应该研究?

我可能缺少一些您真正想要做的事情,但我通常不使用嵌套类型来表示需要动态解析和访问的数据结构

看到您的示例代码,我会使用字典

enum HousingType: Hashable {
    case house(HousingSubType)
    case apartment(HousingSubType)
    case mansion(HousingSubType)

    enum HousingSubType: CaseIterable {
        case victorian
        case modern
        case standard
    }

    var name: String {
        return structures[self]!.name
    }

    static var allCases: [HousingType] {
        return
            HousingType.HousingSubType.allCases.map(HousingType.house)
                + HousingType.HousingSubType.allCases.map(HousingType.apartment)
                + HousingType.HousingSubType.allCases.map(HousingType.mansion)
    }
}

struct Structure {
    let name: String
    let rooms: Int
    let bathrooms: Int
}

let structures: [HousingType: Structure] = [
    .house(.victorian): Structure(
        name: "Victorian House",
        rooms: 4,
        bathrooms: 1
    ),
    .house(.modern): Structure(
        name: "Modern House",
        rooms: 4,
        bathrooms: 4
    ),
    .house(.standard): Structure(
        name: "Standard House",
        rooms: 4,
        bathrooms: 2
    ),
    .apartment(.victorian): Structure(
        name: "Victorian Apartment",
        rooms: 2,
        bathrooms: 1
    ),
    .apartment(.modern): Structure(
        name: "Modern Apartment",
        rooms: 2,
        bathrooms: 2
    ),
    .apartment(.standard): Structure(
        name: "Standard Apartment",
        rooms: 2,
        bathrooms: 1
    ),
    .mansion(.victorian): Structure(
        name: "Victorian Mansion",
        rooms: 10,
        bathrooms: 3
    ),
    .mansion(.modern): Structure(
        name: "Modern Mansion",
        rooms: 10,
        bathrooms: 10
    ),
    .mansion(.standard): Structure(
        name: "Standard Mansion",
        rooms: 10,
        bathrooms: 6
    ),
]

我可能遗漏了您真正想做的事情,但我通常不使用嵌套类型来表示需要动态解析和访问的数据结构

看到您的示例代码,我会使用字典

enum HousingType: Hashable {
    case house(HousingSubType)
    case apartment(HousingSubType)
    case mansion(HousingSubType)

    enum HousingSubType: CaseIterable {
        case victorian
        case modern
        case standard
    }

    var name: String {
        return structures[self]!.name
    }

    static var allCases: [HousingType] {
        return
            HousingType.HousingSubType.allCases.map(HousingType.house)
                + HousingType.HousingSubType.allCases.map(HousingType.apartment)
                + HousingType.HousingSubType.allCases.map(HousingType.mansion)
    }
}

struct Structure {
    let name: String
    let rooms: Int
    let bathrooms: Int
}

let structures: [HousingType: Structure] = [
    .house(.victorian): Structure(
        name: "Victorian House",
        rooms: 4,
        bathrooms: 1
    ),
    .house(.modern): Structure(
        name: "Modern House",
        rooms: 4,
        bathrooms: 4
    ),
    .house(.standard): Structure(
        name: "Standard House",
        rooms: 4,
        bathrooms: 2
    ),
    .apartment(.victorian): Structure(
        name: "Victorian Apartment",
        rooms: 2,
        bathrooms: 1
    ),
    .apartment(.modern): Structure(
        name: "Modern Apartment",
        rooms: 2,
        bathrooms: 2
    ),
    .apartment(.standard): Structure(
        name: "Standard Apartment",
        rooms: 2,
        bathrooms: 1
    ),
    .mansion(.victorian): Structure(
        name: "Victorian Mansion",
        rooms: 10,
        bathrooms: 3
    ),
    .mansion(.modern): Structure(
        name: "Modern Mansion",
        rooms: 10,
        bathrooms: 10
    ),
    .mansion(.standard): Structure(
        name: "Standard Mansion",
        rooms: 10,
        bathrooms: 6
    ),
]

虽然在不了解您想要建模的所有信息和使用它的要求的情况下,很难推荐一种方法,但是可以稍微修改您在示例枚举中使用的方法,以减少代码需求

例如,此实现似乎实现了与您所寻找的相同的初始结果(它为
HousingType.allCases
打印相同的结果,并允许相同的创建和打印单个实例的名称)。但是,它使用了一种稍微不同的方法来显著减少所需的代码行:

enum HousingType: CaseIterable {
    case House(HousingSubType)
    case Apartment(HousingSubType)
    case Mansion(HousingSubType)

    enum HousingSubType: String, CaseIterable {
        case Victorian
        case Modern
        case Standard
    }

    static var allCases: [HousingType] {
        return Array(HousingSubType.allCases.map{ [HousingType.House($0), HousingType.Apartment($0), HousingType.Mansion($0) ] }.joined())
    }

    var name: String {
        switch self {
            case .House(let subtype): return subtype.rawValue + " House"
            case .Apartment(let subtype): return subtype.rawValue + " Apartment"
            case .Mansion(let subtype): return subtype.rawValue + " Mansion"
        }
    }
}

虽然在不了解您想要建模的所有信息和使用它的要求的情况下,很难推荐一种方法,但是可以稍微修改您在示例枚举中使用的方法,以减少代码需求

例如,此实现似乎实现了与您所寻找的相同的初始结果(它为
HousingType.allCases
打印相同的结果,并允许相同的创建和打印单个实例的名称)。但是,它使用了一种稍微不同的方法来显著减少所需的代码行:

enum HousingType: CaseIterable {
    case House(HousingSubType)
    case Apartment(HousingSubType)
    case Mansion(HousingSubType)

    enum HousingSubType: String, CaseIterable {
        case Victorian
        case Modern
        case Standard
    }

    static var allCases: [HousingType] {
        return Array(HousingSubType.allCases.map{ [HousingType.House($0), HousingType.Apartment($0), HousingType.Mansion($0) ] }.joined())
    }

    var name: String {
        switch self {
            case .House(let subtype): return subtype.rawValue + " House"
            case .Apartment(let subtype): return subtype.rawValue + " Apartment"
            case .Mansion(let subtype): return subtype.rawValue + " Mansion"
        }
    }
}

也许你应该用一个类来代替枚举来对这些进行子类化??也许你应该用一个类来代替枚举来对这些进行子类化??这太好了,我不认为使用枚举作为键!这是一种更简单的方法。非常感谢。如果我可能会问,如果enum或者这个方法不是你应该怎么做的话,你会怎么创建一个静态数据结构呢?@BlueGuy,坦率地说,我无法想象你在想什么。但答案可能取决于细节。当我找到更详细的解释时,我会想我会怎么做。这太棒了,没有想到使用枚举作为键!这是一种更简单的方法。非常感谢。如果我可能会问,如果enum或者这个方法不是你应该怎么做的话,你会怎么创建一个静态数据结构呢?@BlueGuy,坦率地说,我无法想象你在想什么。但答案可能取决于细节。当我找到更详细的解释时,我会想我会怎么做。