【问题标题】:Reset a changed Array to its original value Swift将更改后的数组重置为其原始值 Swift
【发布时间】:2020-01-02 20:32:59
【问题描述】:

我有一个数组。我需要使用随机数生成器循环遍历所有数组元素并且不希望重复。

编码新手,我在使用后将数组元素值设置为“”即兴创作。

再次选择数组元素时,我检查新数组的数组元素值是否与原来的相等。如果不是,我输入一个新的随机索引号并重试。


这适用于下面显示的两种方式,直到 restart (startover())

然而

''' 当我设置 remainingQuestions = allQuestions -重启后它不起作用。结果 = 每次重启时文本的(“”/空白)值数量增加。

''' 当我设置 remainingQuestions = questionBank() -它总是有效

但是为什么 >.

澄清:我不明白上述两者之间的区别。两者都应该指向同一个数组?为什么一种有效,一种无效。我所做的只是将剩余问题指向一个包含相同数组的变量。

我的代码无效代码 //注释掉

//Model: File - Question ------------------------------------------

    class Question {

        var questionText : String
        let answer : Bool

        init(text: String, correctAnswer: Bool) {
            questionText = text
            answer = correctAnswer
        }
    }

//Model: File - QuestionBank --------------------------------------

    class QuestionBank {
        var list = [question]()

        init() {

            list.append(Question(text: "", correctAnswer: ""))
        }
    }

//Controller: File - ViewController -------------------------------

    var remainingQuestions = QuestionBank()                             
    //var allQuestions = QuestionBank()
    var questionNumber = Int.random(in: 0..<13)
    var count : Int = 0

    //Iteration snippet: ------------------------------------------

    @IBAction func answerPressed(_ sender: AnyObject) {

        count += 1

        remainingQuestions.list[questionNumber].questionText = ""

        questionNumber = Int.random(in: 0..<13)

        nextQuestion()


    }

        func nextQuestion() {
            if count < 13 {
                if remainingQuestions.list[questionNumber].questionText == questionBank().list[questionNumber].questionText {
                    //this works
                //if remainingQuestions.list[questionNumber].questionText == allQuestions.list[questionNumber].questionText {
                    //this works until startOver()

                    questionLabel.text = remainingQuestions.list[questionNumber].questionText

                } else {
                questionNumber = Int.random(in: 0..<13)
                nextQuestion()
                }

            } else {
                startOver()
        }

        func startOver() {
            count = 0
            score = 0
            remainingQuestions = QuestionBank() //This works
            // remainingQuestions = allQuestions (This doesn't work (why!?))
            nextQuestion()
    }

【问题讨论】:

  • 您是否尝试随机化数组元素的顺序?例如,您有 n 个问题,并且您想一个接一个地显示它们,但顺序是随机的,而不是显示相同的问题两次?
  • @DonMag - 是的。尝试并成功:) 这是我遇到问题的重启功能。意思是重新做测验。
  • 您将问题标记为swift3 ...您真的在使用 Swift 3 吗?最简单的方法是打乱数组(或打乱索引),然后简单地遍历该打乱的数组。
  • 是的,正如我所说,我是编码新手,所以我即兴创作了一个解决方案。我相信他们有很多更好的方法。到目前为止,我已尽我所能。
  • @DonMag - 我一定会查一下洗牌,谢谢你的帮助

标签: arrays swift xcode swift3


【解决方案1】:

给你一个洗牌数组的实际例子......

在任何视图控制器的viewDidLoad() 中添加这个:

let questions:[String] = [
    "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"
]
for _ in 1...4 {
    let shuffledQuestions:[String] = questions.shuffled()
    print(shuffledQuestions)
}

当您运行此程序时,您将在调试控制台中看到问题数组输出四次,每次以随机顺序输出。它看起来像这样:

["Six", "Nine", "One", "Five", "Four", "Two", "Ten", "Three", "Eight", "Seven"]
["Two", "Nine", "Seven", "Four", "Six", "Five", "Eight", "One", "Three", "Ten"]
["Nine", "Ten", "Four", "Two", "One", "Five", "Eight", "Three", "Six", "Seven"]
["Six", "Three", "Seven", "One", "Five", "Two", "Eight", "Nine", "Four", "Ten"]

当然,每次运行,顺序都会不同。

所以,这里有一个简单的 10 题真/假测验的完整示例,问题顺序是随机的(打乱的)。回答完第 10 个问题后,您可以点击“重新开始测验”按钮,您将得到相同的 10 个问题,但顺序不同:

//Model: File - Question ------------------------------------------

class Question {

    var questionText : String
    let answer : Bool

    init(text: String, correctAnswer: Bool) {
        questionText = text
        answer = correctAnswer
    }
}

//Model: File - QuestionBank --------------------------------------

class QuestionBank {
    var list: [Question] = [
        Question(text: "One is an Even number?",   correctAnswer: false),
        Question(text: "Two is an Even number?",   correctAnswer: true),
        Question(text: "Three is an Even number?", correctAnswer: false),
        Question(text: "Four is an Even number?",  correctAnswer: true),
        Question(text: "Five is an Even number?",  correctAnswer: false),
        Question(text: "Six is an Even number?",   correctAnswer: true),
        Question(text: "Seven is an Even number?", correctAnswer: false),
        Question(text: "Eight is an Even number?", correctAnswer: true),
        Question(text: "Nine is an Even number?",  correctAnswer: false),
        Question(text: "Ten is an Even number?",   correctAnswer: true),
    ]
}

class RandomizeQuestionsViewController: UIViewController {

    let questionHeaderLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .cyan
        v.numberOfLines = 0
        v.textAlignment = .center
        return v
    }()

    let questionLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .yellow
        v.numberOfLines = 0
        v.textAlignment = .center
        return v
    }()

    let answerLabel: UILabel = {
        let v = UILabel()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .yellow
        v.numberOfLines = 0
        v.textAlignment = .center
        return v
    }()

    let nextButton: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .blue
        v.setTitle("Next Question", for: .normal)
        return v
    }()

    let restartButton: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .red
        v.setTitle("Restart Quiz", for: .normal)
        return v
    }()

    let trueButton: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
        v.setTitleColor(.lightGray, for: .disabled)
        v.setTitleColor(.blue, for: .normal)
        v.layer.borderColor = UIColor.red.cgColor
        v.setTitle("True", for: .normal)
        return v
    }()

    let falseButton: UIButton = {
        let v = UIButton()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = UIColor(white: 0.9, alpha: 1.0)
        v.setTitleColor(.blue, for: .normal)
        v.setTitleColor(.lightGray, for: .disabled)
        v.layer.borderColor = UIColor.red.cgColor
        v.setTitle("False", for: .normal)
        return v
    }()


    var shuffledQuestions: [Question] = [Question]()

    // arrays are zero-based
    var currentQuestionIndex: Int = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        // add UI elements
        view.addSubview(questionHeaderLabel)
        view.addSubview(questionLabel)
        view.addSubview(trueButton)
        view.addSubview(falseButton)
        view.addSubview(answerLabel)
        view.addSubview(nextButton)
        view.addSubview(restartButton)

        NSLayoutConstraint.activate([

            questionHeaderLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 40.0),
            questionHeaderLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0),
            questionHeaderLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0),
            questionHeaderLabel.heightAnchor.constraint(equalToConstant: 30.0),

            questionLabel.topAnchor.constraint(equalTo: questionHeaderLabel.bottomAnchor, constant: 0.0),
            questionLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0),
            questionLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0),
            questionLabel.heightAnchor.constraint(equalToConstant: 80.0),

            trueButton.topAnchor.constraint(equalTo: questionLabel.bottomAnchor, constant: 40.0),
            trueButton.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: -60.0),
            trueButton.widthAnchor.constraint(equalToConstant: 90.0),

            falseButton.topAnchor.constraint(equalTo: questionLabel.bottomAnchor, constant: 40.0),
            falseButton.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 60.0),
            falseButton.widthAnchor.constraint(equalToConstant: 90.0),

            answerLabel.topAnchor.constraint(equalTo: trueButton.bottomAnchor, constant: 40.0),
            answerLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0),
            answerLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0),
            answerLabel.heightAnchor.constraint(equalToConstant: 80.0),

            nextButton.topAnchor.constraint(equalTo: answerLabel.bottomAnchor, constant: 40.0),
            nextButton.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),
            nextButton.widthAnchor.constraint(equalToConstant: 160.0),

            restartButton.topAnchor.constraint(equalTo: answerLabel.bottomAnchor, constant: 40.0),
            restartButton.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0),
            restartButton.widthAnchor.constraint(equalToConstant: 160.0),

            ])

        trueButton.addTarget(self, action: #selector(trueTapped(_:)), for: .touchUpInside)
        falseButton.addTarget(self, action: #selector(falseTapped(_:)), for: .touchUpInside)
        nextButton.addTarget(self, action: #selector(nextQuestionTapped(_:)), for: .touchUpInside)
        restartButton.addTarget(self, action: #selector(restartQuizTapped(_:)), for: .touchUpInside)

        restartQuizTapped(nil)

    }

    @objc func restartQuizTapped(_ sender: Any?) -> Void {

        // hide restart button
        restartButton.isHidden = true

        // nextQuestion func increments the index...
        // set it to -1 so the first question will be index 0
        currentQuestionIndex = -1

        // shuffle the questions
        shuffledQuestions = QuestionBank().list.shuffled()

        // show the question
        nextQuestionTapped(nil)

    }

    @objc func nextQuestionTapped(_ sender: Any?) -> Void {

        // hide next button
        nextButton.isHidden = true

        // reset true/false button borders
        trueButton.layer.borderWidth = 0
        falseButton.layer.borderWidth = 0

        // increment the index
        currentQuestionIndex += 1

        if currentQuestionIndex < shuffledQuestions.count {

            // get current Question object from shuffled array
            let q: Question = shuffledQuestions[currentQuestionIndex]

            // set the label texts
            questionHeaderLabel.text = "Question \(currentQuestionIndex + 1) of \(shuffledQuestions.count)"
            questionLabel.text = q.questionText
            answerLabel.text = "Select True or False"

            // enable true/false buttons
            trueButton.isEnabled = true
            falseButton.isEnabled = true

        } else {

            // out of questions, so show restart button
            restartButton.isHidden = false

        }

    }

    @objc func trueTapped(_ sender: Any?) -> Void {

        // highlight selected button
        trueButton.layer.borderWidth = 3

        // get current Question object from shuffled array
        let q: Question = shuffledQuestions[currentQuestionIndex]

        var answerText = ""

        if q.answer == true {
            answerText = "Correct!" + "\n" + "It IS an Even number!"
        } else {
            answerText = "Wrong!" + "\n" + "It is NOT an Even number!"
        }

        updateUI(feedback: answerText)

    }

    @objc func falseTapped(_ sender: Any?) -> Void {

        // highlight selected button
        falseButton.layer.borderWidth = 3

        // get current Question object from shuffled array
        let q: Question = shuffledQuestions[currentQuestionIndex]

        var answerText = ""

        if q.answer == false {
            answerText = "Correct!" + "\n" + "It is NOT an Even number!"
        } else {
            answerText = "Wrong!" + "\n" + "It IS an Even number!"
        }

        updateUI(feedback: answerText)

    }

    func updateUI(feedback answer: String) -> Void {

        answerLabel.text = answer

        // disable true/false buttons
        trueButton.isEnabled = false
        falseButton.isEnabled = false

        // if there are more questions
        if currentQuestionIndex < shuffledQuestions.count - 1 {
            // show next question button
            nextButton.isHidden = false
        } else {
            // show restart button
            restartButton.isHidden = false
        }

    }

}

这都是基于代码的,所以没有@IBOutlets 或@IBActions ...只需从一个新的视图控制器开始,并将其类分配给RandomizeQuestionsViewController

【讨论】:

    【解决方案2】:

    我会做一些不同的事情。您的示例中缺少很多代码,因此需要进行一些更改,但要点如下:

    import UIKit
    
    class Question {
    
      let questionText : String
      let answer : Bool
    
      init(text: String, correctAnswer: Bool) {
        questionText = text
        answer = correctAnswer
      }
    }
    
    //Model: File - QuestionBank --------------------------------------
    
    class QuestionBank {
      var list = [Question]()
    
      init() {
        list.append(Question(text: "", correctAnswer: false))
      }
    
      init(list: [Question]) {
        self.list = list
      }
    
      func pop() -> Question? {
        guard list.count > 0 else {
          return nil
        }
        return list.removeFirst()
      }
    }
    
    
    
    //Controller: File - ViewController -------------------------------
    
    var remainingQuestions = QuestionBank()
    var allQuestions = QuestionBank()
    
    //Iteration snippet: ------------------------------------------
    
    func answerPressed() {
      nextQuestion()
    }
    
    func nextQuestion() {
      guard let nextQuestion = remainingQuestions.pop() else {
          print("no questions left")
          startOver()
          return
      }
          questionLabel.text = nextQuestion.questionText
      }
    
      func startOver() {//also call on first setup
        remainingQuestions = QuestionBank(list: allQuestions.list.shuffled())
    
        nextQuestion()
      }
    

    【讨论】:

    • 感谢替代方法!我现在没有时间,但以后一定要研究它。我试图只包含必要的代码,所以你不必看到我的整个项目 lol
    • 虽然我的问题是为什么我的代码的一个版本有效而​​另一个没有
    猜你喜欢
    • 2017-03-21
    • 2015-07-10
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 2017-04-27
    相关资源
    最近更新 更多