Как сделать вложенные вопросы в анкете? Я не совсем понимаю - PullRequest
0 голосов
/ 02 мая 2019

Я делаю несколько анкет.В общем, я создал модель, в которой полностью прописал вопросы и ответы, как и должно быть на самом деле.Но какая обработка должна быть в заявке, если я хочу не только задавать вопросы один за другим, но и задавать конкретный уникальный вопрос в зависимости от последнего ответа?(вероятно, это называется «вопросник с выбором переплетенных ответов») Появление следующего вопроса или результата будет зависеть от последнего ответа.Как реализовать это в модели?

Я хочу сделать так же, как в этой схеме .

struct PossibleAnswer {
var text: String
var type: TypeOfLanguage
var nextQuestion: Question? 

}

enum TypeOfLanguage: String {
case python = "Python"
case java = "Java"
case c = "C"
case cPlusPlus = "C++"
case javaScript = "JavaScript"
case cSharp = "C#"
case ruby = "Ruby"
case php = "PHP"
case swift = "Swift"
case next

var definition: String {
    switch self {
    case .python:
        return "Some text"
    case .java:
        return "Some text"
    case .c:
        return "Some text"
    case .cPlusPlus:
        return "Some text"
    case .javaScript:
        return "Some text"
    case .cSharp:
        return "Some text"
    case .ruby:
        return "Some text"
    case .php:
        return "Some text"
    case .swift:
        return "Some text"
    case .next:
        return ""
    }
}

}

struct Question {
var text: String
var answers: [PossibleAnswer]

static func loadData() -> [Question] {
    return [Question(text: "Why do you want to learn programming?", answers: [
        PossibleAnswer(text: "For my kids", type: .python, nextQuestion: nil),
        PossibleAnswer(text: "Make money", type: .next, nextQuestion:
            Question(text: "Make money", answers: [
            PossibleAnswer(text: "Get a job", type: .next, nextQuestion:
                Question(text: "Which platform/field?", answers: [
                    PossibleAnswer(text: "I want to work for big tech companies", type: .next, nextQuestion:
                        Question(text: "Which one?", answers: [
                            PossibleAnswer(text: "Facebook", type: .python, nextQuestion: nil),
                            PossibleAnswer(text: "Google", type: .python, nextQuestion: nil),
                            PossibleAnswer(text: "Microsoft", type: .cSharp, nextQuestion: nil),
                            PossibleAnswer(text: "Apple", type: .swift, nextQuestion: nil)])),
                    PossibleAnswer(text: "Doesn't matter, i just want money!", type: .java, nextQuestion: nil)]))]))])]}}

1 Ответ

1 голос
/ 02 мая 2019

Есть несколько подходов, которые вы можете использовать:

  1. Вы можете определить ID для Вопроса и Ответа и использовать его. Как это:
struct Identifier<T>: Hashable {
    let value: String

    func hash(into hasher: inout Hasher) {
        hasher.combine(value)
    }
}

struct Answer {
    let id: Identifier<Answer>
    let text: String
    var nextQuestion: Identifier<Question>?
}

struct Question {
    let id: Identifier<Question>
    let text: String
    var answers: [Answer] = []
}

var allQuestions: [Identifier<Question>: Question] = [:]

let answer = Answer(id: Identifier(value: "answer id"), text: "Answer text", nextQuestion: Identifier(value: "Q 2"))

let deadendAnswer = Answer(id: Identifier(value: "deadendAnswer id"), text: "Deadend Answer text", nextQuestion: nil)

let question1 = Question(id: Identifier(value: "Q 1"), text: "Question 1", answers: [answer, deadendAnswer])

let question2 = Question(id: Identifier(value: "Q 2"), text: "Question 2", answers: [])

allQuestions[question1.id] = question1
allQuestions[question2.id] = question2

func nextQuestion(for answer: Answer) -> Question? {
    guard let id = answer.nextQuestion else {
        return nil
    }
    return allQuestions[id]
}
  1. Вы можете переключить struct на class, и поскольку swift struct является типом значения и не может использоваться для рекурсивных структур. Но class является ссылочным типом, и рекурсия будет работать нормально.

  2. В качестве альтернативы, вы все еще можете использовать struct, но сохранить nextQuestion в качестве ссылки:

struct Question {
    let text: String
    var answers: [Answer] = []
}

struct Answer {
    let text: String
    var nextQuestion: Container<Question>?
}

class Container<T> {
    let value: T

    init(_ value: T) {
        self.value = value
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...