使用嵌套枚举创建问题向下钻取

问题描述 投票:0回答:2

我有一个视图控制器,它将向用户显示“问题向下钻取”,其中回答一个问题会显示基于先前答案的下一个分配问题。我正在尝试找出构建此“问题深入分析”的最佳方法。

我假设嵌套枚举是可行的方法。这是我目前拥有的设置示例:

enum SubmissionSteps {
    case techQuestion(TechQuestionStep)
    
    enum TechQuestionStep {
        case website(WebsiteStep), app, password, other
        
        enum WebsiteStep {
            case yesStreaming(YesStreamingStep), noStreaming
            
            enum YesStreamingStep {
                case startTime(StartTimeStep)
                
                enum StartTimeStep {
                    case endTime
                }
            }
        }
    }
}

func showFirstStep() {
    currentStep = SubmissionSteps.techQuestion // error here 'ViewController' has no member 'techQuestion'
}

var currentStep:SubmissionSteps? {
    didSet {
        
    }
}

var currentlyShowing:[SubmissionSteps] = [] {
    didSet {
        
    }
}

func getStepTitle(step:SubmissionSteps) -> String {
    switch step {
        
    case .techQuestion(_):
        return "Tech Question"
    case .techQuestion(.app):
        return "App" // Case is already handled by previous patterns;
    case .techQuestion(.other):
        return "Other" // Case is already handled by previous patterns;
    case .techQuestion(.password):
        return "Password" // Case is already handled by previous patterns;
    case .techQuestion(.website(_)):
        return "Website" // Case is already handled by previous patterns;
    case .techQuestion(.website(.noStreaming)):
        return "No Streaming" // Case is already handled by previous patterns;
    case .techQuestion(.website(.yesStreaming(_))):
        return "Yes Streaming" // Case is already handled by previous patterns;
    case .techQuestion(.website(.yesStreaming(.startTime(_)))):
        return "Start Time" // Case is already handled by previous patterns;
    case .techQuestion(.website(.yesStreaming(.startTime(.endTime)))):
        return "End Time" // Case is already handled by previous patterns;
    }
}

上述设置的问题存在于

getStepTitle()
函数中。我无法返回父选项的标题,只能返回子项的标题。我目前拥有的
getStepTitle()
函数中的 switch 语句显示“案例已由以前的模式处理;考虑删除它”。

我也不能将

currentStep
设置为枚举中的父选项,只有孩子。

使用嵌套枚举不是处理这样的数据设置的正确方法,或者我对如何访问嵌套枚举中的父值以获取枚举中任何级别的当前标题有一个基本的误解。建议或想法?

swift enums enumeration
2个回答
1
投票

您当前使用的枚举关联值不允许您创建“父”值。例如,

currentStep = SubmissionSteps.techQuestion
不起作用,因为
techQuestion
需要关联值。

我看到两个解决方案。

  1. 使关联值可选。
  2. 创建一个新的
    case
    来代表“顶级”级别。

对于解决方案 1,您的嵌套枚举变为:

enum SubmissionSteps {
    case techQuestion(TechQuestionStep?)

    enum TechQuestionStep {
        case website(WebsiteStep?), app, password, other

        enum WebsiteStep {
            case yesStreaming(YesStreamingStep?), noStreaming

            enum YesStreamingStep {
                case startTime(StartTimeStep?)

                enum StartTimeStep {
                    case endTime
                }
            }
        }
    }
}

你可以创建一个“父母”

techQuestion

currentStep = SubmissionSteps.techQuestion(nil)

您通过将最具体的案例放在第一位,将最一般的案例放在最后来解决

getStepTitle
的问题:

func getStepTitle(step:SubmissionSteps) -> String {
    switch step {

    case .techQuestion(.website(.yesStreaming(.startTime(.endTime)))):
        return "End Time"
    case .techQuestion(.website(.yesStreaming(.startTime(_)))):
        return "Start Time"
    case .techQuestion(.website(.yesStreaming(_))):
        return "Yes Streaming"
    case .techQuestion(.website(.noStreaming)):
        return "No Streaming"
    case .techQuestion(.website(_)):
        return "Website"
    case .techQuestion(.password):
        return "Password"
    case .techQuestion(.other):
        return "Other"
    case .techQuestion(.app):
        return "App"
    case .techQuestion(_):
        return "Tech Question"
    }
}

对于解决方案 2,您的嵌套枚举变成如下内容:

enum SubmissionSteps {
    case techQuestion(TechQuestionStep)

    enum TechQuestionStep {
        case top
        case website(WebsiteStep), app, password, other

        enum WebsiteStep {
            case top
            case yesStreaming(YesStreamingStep), noStreaming

            enum YesStreamingStep {
                case top
                case startTime(StartTimeStep)

                enum StartTimeStep {
                    case endTime
                }
            }
        }
    }
}

你可以创建一个“父母”

techQuestion

currentStep = SubmissionSteps.techQuestion(.top)

getStepTitle
的修复是一样的。


至于你的陈述:“我假设嵌套枚举是可行的方法。”,这是一个完全超出这里范围的其他讨论。


0
投票

您的第一个案例

case .techQuestion(_):
将匹配 any techQuestion,无论子类型如何。一旦你有了那个案例,你就不能再有更具体的案例了。摆脱这种情况并单独处理每个子类型,或者将您的
case .techQuestion(_):
移动到其他
case .techQuestion()
案例下方,这样它只会捕获没有特定子类型之一的 .techQuestion 类型。

考虑这个示例项目:

import Foundation

enum Bar {
    case bar1
    case bar2
    case bar3
}

enum Foo {
    case foo1(Bar?)
    case foo2
}


let aFooBar1: Foo = .foo1(.bar1)
let aFooBar2: Foo = .foo1(.bar2)
let aFoo: Foo = .foo2



func talkboutAFoo(_ aFoo: Foo) {
    switch aFoo {
    case .foo1(nil):
        print("Foo(no bar)")
    case .foo1(.bar1):
        print("foo1(.bar1)")
    case .foo1(.bar2):
        print("foo1(.bar2)")
    case .foo1(_): // Catch-all that matches other foo1 subtypes
        print("foo1(_)")
    default:
        print("some other case")
    }

}

talkboutAFoo(Foo.foo1(.bar1))
talkboutAFoo(Foo.foo1(.bar2))
talkboutAFoo(Foo.foo1(.bar3))
talkboutAFoo(Foo.foo2)
talkboutAFoo(Foo.foo1(nil))

输出

foo1(.bar1)
foo1(.bar2)
foo1(_)
some other case
Foo(no bar)
© www.soinside.com 2019 - 2024. All rights reserved.