Ios 从8组问题中随机挑选问题的测验应用程序?

Ios 从8组问题中随机挑选问题的测验应用程序?,ios,json,swift,Ios,Json,Swift,我为iOS构建了一个应用程序,我想让它从8组不同的问题中随机挑选问题。问题数量为356个,其中只有50个必须随机挑选 第1组的8个问题 第二组的5个问题 第三组的5个问题 第四组的6个问题 第五组的6个问题 第六组的5个问题 第七组的9个问题 第八组的6个问题 总共:50个问题。 我所做的是,我建立了测验,但它阅读了所有的问题并向用户展示。这些问题是从.json文件中读取的 这是我的代码: (因为没有对代码的注释,请询问我。) 这个.json文件只是一个例子,每个小组都有更多的问题。每个小组大约

我为iOS构建了一个应用程序,我想让它从8组不同的问题中随机挑选问题。问题数量为356个,其中只有50个必须随机挑选

  • 第1组的8个问题
  • 第二组的5个问题
  • 第三组的5个问题
  • 第四组的6个问题
  • 第五组的6个问题
  • 第六组的5个问题
  • 第七组的9个问题
  • 第八组的6个问题
  • 总共:50个问题。

    我所做的是,我建立了测验,但它阅读了所有的问题并向用户展示。这些问题是从.json文件中读取的

    这是我的代码: (因为没有对代码的注释,请询问我。)


    这个.json文件只是一个例子,每个小组都有更多的问题。每个小组大约有45个问题。

    我建议您创建一个新的.json文件,其中包含8个不同组中的8组问题,如问题1、问题2等。。在这之后,如果随机挑选的问题数量是每个小组想要的数量,则使用开关创建8个案例,并打破每个案例。

    根据您的
    数据。json
    ,您将收到一个包含356个问题的列表。“8组*只是组名称,每个“问题”的一个“属性”就是组

    如果您实际收到的是一组问题中的数据,那么第一步是将它们附加到一个组中,如您所示

    那么,如何显示356个问题列表中的50个随机问题

    • 生成一个从零到355的数字数组(数组是基于零的)
    • 洗牌这个数组。有很多很好的例子-这里有一个相当全面的参考:
    数组的前50个元素现在包含0到355之间的随机(无重复)值,因此您可以简单地按该顺序显示实际问题


    编辑:

    如果要求包括每组预先确定的问题数量,则只需再添加几个步骤:

    不要使用一个包含所有356个问题的大数组,而是将json数据拆分为8个数组,每个数组包含属于特定组的问题

    然后,将这些数组添加到“组”的二维数组中

    接下来,构建一个问题“ID”编号的二维数组——简单地说是一个从0到每组问题数量的序列——然后洗牌每个数组

    结果将是每组随机问题的X个数量

    下面是一个可以在游乐场页面中运行的简单示例。代码生成问题对象数组,以及相应的无序排列的“索引”数组。点击“下一个问题”按钮将逐步查看结果


    导入UIKit
    导入PlaygroundSupport
    //简单随机数函数
    func random(u-range:range)->Int{
    返回range.lowerBound+Int(arc4random_统一(UInt32(range.upperBound-range.lowerBound)))
    }
    //洗牌扩展
    扩展MutableCollection,其中Index.Iterator.Element==索引{
    ///洗牌此集合的内容。
    变异func shuffle(){
    让c=计数
    保护c>1其他{return}
    对于zip中的(firstUnshuffled,unshuffledCount)(索引,步幅(从:c到:1,由:-1){
    设d:IndexDistance=numericCast(arc4random_统一(numericCast(unsuffledcount)))
    保护d!=0其他{继续}
    设i=索引(第一个未缓冲,抵消者:d)
    交换(&self[firstUnshuffled],&self[i])
    }
    }
    }
    扩展序列{
    ///返回包含此序列内容的数组,无序排列。
    func shuffled()->[Iterator.Element]{
    var结果=数组(自身)
    result.shuffle()
    返回结果
    }
    }
    //问题对象
    结构问题{
    问:字符串!
    var回答:[字符串]!
    回答:Int!
    初始化(项:[字符串:任意])
    {
    self.Question=项目[“问题”]作为?字符串
    self.Answers=项[“Answers”]作为?[字符串]
    self.Answer=item[“Answer”]as?Int
    }
    }
    //标准UIViewController
    类TestViewController:UIViewController{
    //标准UIButton
    让btn:UIButton={
    设b=UIButton()
    b、 setTitle(“下一个问题”,用于:。正常)
    b、 背景颜色=.red
    b、 translatesAutoresizingMaskIntoConstraints=false
    返回b
    }()
    //标准UILabel
    let questionLabel:UILabel={
    设v=UILabel()
    v、 背景颜色=白色
    v、 numberOfLines=0
    v、 translatesAutoresizingMaskIntoConstraints=false
    返回v
    }()
    //问题对象的二维数组
    var arrayOfQuestions=[[问题]]()
    //无序索引值的二维数组
    var arrayOfIDs=[[Int]]()
    //每组的问题数
    让问题分组=[8,5,5,6,6,5,9,6]
    //注意:数组是基于零的,
    //所以“第一个问题”指数将为零
    //“第一组”指数将为零
    //在-1处启动问题计数器,使“下一个问题”为零
    var currentQuestion:Int=-1
    //组计数器
    var currentGroup:Int=0
    重写func viewDidLoad(){
    super.viewDidLoad()
    //这只是生成了8组问题,如下所示:
    //{“问题”:“小组:1问题:1”,“答案”:[“A”、“B”、“C”、“D”],“答案”:1}
    对于1…8中的I组{
    //每组将有43到48个问题
    
    让numQuestions=random(43..不要把逻辑和代码弄乱

    如果您担心时间复杂性-难以实现,请遵循此操作 只需遵循下面的算法

    因为您有8个组,所以创建一个整数数组,该数组最多可以容纳8个值,并使用所有0进行初始化

    Array(1)  =   [0 0 0 0 0 0 0 0]
    
    并创建另一个保存最大值的数组
    [ {"Question":"Group 1. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 1. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 1. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 3},
      {"Question":"Group 2. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 2. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 1},
      {"Question":"Group 2. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 3. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 3. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 4. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 4. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 3},
      {"Question":"Group 4. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 5. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 0},
      {"Question":"Group 5. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 6. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 0},
      {"Question":"Group 7. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},
      {"Question":"Group 8. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 0},
      {"Question":"Group 8. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 1},
      {"Question":"Group 9. lalala?", "Answers":["lala","trtr","asas","bbbb"],"Answer": 2},]
    
    import UIKit
    import PlaygroundSupport
    
    // simple random number function
    func random(_ range:Range<Int>) -> Int {
        return range.lowerBound + Int(arc4random_uniform(UInt32(range.upperBound - range.lowerBound)))
    }
    
    // shuffling extension
    extension MutableCollection where Indices.Iterator.Element == Index {
        /// Shuffles the contents of this collection.
        mutating func shuffle() {
            let c = count
            guard c > 1 else { return }
    
            for (firstUnshuffled , unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
                let d: IndexDistance = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
                guard d != 0 else { continue }
                let i = index(firstUnshuffled, offsetBy: d)
                swap(&self[firstUnshuffled], &self[i])
            }
        }
    }
    
    extension Sequence {
        /// Returns an array with the contents of this sequence, shuffled.
        func shuffled() -> [Iterator.Element] {
            var result = Array(self)
            result.shuffle()
            return result
        }
    }
    
    // Question object
    struct Question {
        var Question: String!
        var Answers: [String]!
        var Answer: Int!
    
        init(item: [String: Any])
        {
            self.Question = item["Question"] as? String
            self.Answers = item["Answers"] as? [String]
            self.Answer = item["Answer"] as? Int
        }
    }
    
    // standard UIViewController
    class TestViewController : UIViewController {
    
        // standard UIButton
        let btn: UIButton = {
            let b = UIButton()
            b.setTitle("  Next Question  ", for: .normal)
            b.backgroundColor = .red
            b.translatesAutoresizingMaskIntoConstraints = false
            return b
        }()
    
        // standard UILabel
        let questionLabel: UILabel = {
            let v = UILabel()
            v.backgroundColor = .white
            v.numberOfLines = 0
            v.translatesAutoresizingMaskIntoConstraints = false
            return v
        }()
    
        // two-dimensional array of Question objects
        var arrayOfQuestions = [[Question]]()
    
        // two-dimension array of shuffled Index values
        var arrayOfIDs = [[Int]]()
    
        // number of questions per group
        let questionsPerGroup = [8, 5, 5, 6, 6, 5, 9, 6]
    
        // note: arrays are Zero-based, 
        //  so "first question" index will be Zero
        //  and "first group" index will be Zero
    
        // start Question counter at -1 so "next question" will be Zero
        var currentQuestion: Int = -1
    
        // group counter
        var currentGroup: Int = 0
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // this is just generating 8 groups of Questions that look like:
            // {"Question":"Group: 1 Question: 1", "Answers":["A", "B", "C", "D"], "Answer":1}
    
            for iGroup in 1...8 {
    
                //  each group will have between 43 and 48 questions
                let numQuestions = random(43..<49)
    
                // new empty array
                var aGroup = [Question]()
    
                for iQuestion in 1...numQuestions {
    
                    let s: [String:Any] = [
                        "Question":"Group: \(iGroup) Question: \(iQuestion)",
                        "Answers":["A", "B", "C", "D"],
                        "Answer": random(0..<3)
                    ]
    
                    let q = Question(item: s)
    
                    aGroup.append(q)
    
                }
    
                // append this "group" to the array
                arrayOfQuestions.append(aGroup)
    
                // create array of numbers 0 through number of questions -1
                let aIDs = Array(0..<numQuestions)
    
                // shuffle that array and append to "IDs" array
                arrayOfIDs.append(aIDs.shuffled())
    
            }
    
            // add a button and label to the view
            self.view.addSubview(btn)
            self.view.addSubview(questionLabel)
    
            btn.topAnchor.constraint(equalTo: view.topAnchor, constant: 40.0).isActive = true
            btn.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0.0).isActive = true
    
            questionLabel.topAnchor.constraint(equalTo: btn.bottomAnchor, constant: 20.0).isActive = true
            questionLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16.0).isActive = true
            questionLabel.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -16.0).isActive = true
    
            // add touch up target to the button
            btn.addTarget(self, action: #selector(didTap(_:)), for: .touchUpInside)
    
            // show the first question
            showNextQuestion()
    
        }
    
        func showNextQuestion() -> Void {
    
            // increment currentQuestion
            currentQuestion += 1
    
            // if we are past the number of questions in this group
            //  set currentQuestion back to Zero and increment currentGroup
            if currentQuestion == questionsPerGroup[currentGroup] {
                currentQuestion = 0
                currentGroup += 1
            }
    
            // if we are past the last group, show a message
            if currentGroup == questionsPerGroup.count {
                questionLabel.text = "End of quiz"
            } else {
    
                // get the question ID from the shuffled IDs of the current group
                let idx = arrayOfIDs[currentGroup][currentQuestion]
    
                // get that question object from the array
                let thisQuestion = arrayOfQuestions[currentGroup][idx]
    
                // get the question parts
                let sQuestion = thisQuestion.Question ?? "missing data"
                let aAnswers = thisQuestion.Answers ?? ["missing data"]
                let iAnswer = thisQuestion.Answer ?? -1
    
                // show them in our label
                questionLabel.text = "\nThis is Question: \(currentQuestion + 1) of Group: \(currentGroup + 1)\n\n" +
                    "\(sQuestion)\n" +
                    "\(aAnswers)\n" +
                    "\(iAnswer)\n"
            }
    
        }
    
        func didTap(_ sender: Any?) -> Void {
            showNextQuestion()
        }
    
    }
    
    let vc = TestViewController()
    vc.view.backgroundColor = .blue
    PlaygroundPage.current.liveView = vc
    
    Array(1)  =   [0 0 0 0 0 0 0 0]
    
    Array(2)  =   [8 5 5 6 6 5 9 6]
    
    n[]   =  [ 8elements ] not mensioned in question
    
     func pickQuestion ()
    {
        if Questions.count > 0 && questionscount < 8{
            QNumber = Int(arc4random_uniform(UInt32(Questions.filter{$0.Question.hasPrefix("KEK")}.count)))
            questionscount += 1
            questionLabel.text = Questions.filter{$0.Question.hasPrefix("KEK")}[QNumber].Question
    
            self.title = "Ερώτηση: \(Int(questionscount))/50"
            answerNumber = Questions[QNumber].Answer
    
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions[QNumber].Answers[i], for: UIControlState.normal)
            }
            print(QNumber)
            Questions.remove(at: QNumber)
    
        }else if Questions.count > 0 && questionscount < 13{
    
            QNumber = Int(arc4random_uniform(UInt32(Questions.filter{$0.Question.hasPrefix("M")}.count)))
            questionscount += 1
            questionLabel.text = Questions.filter{$0.Question.hasPrefix("M")}[QNumber].Question
    
            self.title = "Ερώτηση: \(Int(questionscount))/50"
            answerNumber = Questions.filter{$0.Question.hasPrefix("M")}[QNumber].Answer
    
    
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions.filter{$0.Question.hasPrefix("M")}[QNumber].Answers[i], for: UIControlState.normal)
            }
            print(QNumber)
            Questions.remove(at: QNumber)
    
        }else if Questions.count > 0 && questionscount < 18{
            QNumber = Int(arc4random_uniform(UInt32(Questions.filter{$0.Question.hasPrefix("N")}.count)))
            questionscount += 1
            questionLabel.text = Questions.filter{$0.Question.hasPrefix("N")}[QNumber].Question
    
    
            self.title = "Ερώτηση: \(Int(questionscount))/50"
            answerNumber = Questions.filter{$0.Question.hasPrefix("N")}[QNumber].Answer
    
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions.filter{$0.Question.hasPrefix("N")}[QNumber].Answers[i], for: UIControlState.normal)
            }
            Questions.remove(at: QNumber)
    
        }else if Questions.count > 0 && questionscount < 24{
            QNumber = Int(arc4random_uniform(UInt32(Questions.filter{$0.Question.hasPrefix("A")}.count)))
            questionscount += 1
            questionLabel.text = Questions.filter{$0.Question.hasPrefix("A")}[QNumber].Question
    
            self.title = "Ερώτηση: \(Int(questionscount))/50"
            answerNumber = Questions.filter{$0.Question.hasPrefix("A")}[QNumber].Answer
    
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions.filter{$0.Question.hasPrefix("A")}[QNumber].Answers[i], for: UIControlState.normal)
            }
            Questions.remove(at: QNumber)
    
        }else if Questions.count > 0 && questionscount < 30{
            QNumber = Int(arc4random_uniform(UInt32(Questions.filter{$0.Question.hasPrefix("ΑΔ")}.count)))
            questionscount += 1
            questionLabel.text = Questions.filter{$0.Question.hasPrefix("ΑΔ")}[QNumber].Question
    
            self.title = "Ερώτηση: \(Int(questionscount))/50"
            answerNumber = Questions.filter{$0.Question.hasPrefix("ΑΔ")}[QNumber].Answer
    
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions.filter{$0.Question.hasPrefix("ΑΔ")}[QNumber].Answers[i], for: UIControlState.normal)
            }
            Questions.remove(at: QNumber)
    
        }else if Questions.count > 0 && questionscount < 35{
            QNumber = Int(arc4random_uniform(UInt32(Questions.filter{$0.Question.hasPrefix("ΕΠ")}.count)))
            questionscount += 1
            questionLabel.text = Questions.filter{$0.Question.hasPrefix("ΕΠ")}[QNumber].Question
    
            self.title = "Ερώτηση: \(Int(questionscount))/50"
            answerNumber = Questions.filter{$0.Question.hasPrefix("ΕΠ")}[QNumber].Answer
    
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions.filter{$0.Question.hasPrefix("ΕΠ")}[QNumber].Answers[i], for: UIControlState.normal)
            }
            Questions.remove(at: QNumber)
    
        }else if Questions.count > 0 && questionscount < 44{
            QNumber = Int(arc4random_uniform(UInt32(Questions.filter{$0.Question.hasPrefix("T")}.count)))
            questionscount += 1
            questionLabel.text = Questions.filter{$0.Question.hasPrefix("T")}[QNumber].Question
    
            self.title = "Ερώτηση: \(Int(questionscount))/50"
            answerNumber = Questions.filter{$0.Question.hasPrefix("T")}[QNumber].Answer
    
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions.filter{$0.Question.hasPrefix("T")}[QNumber].Answers[i], for: UIControlState.normal)
            }
            Questions.remove(at: QNumber)
    
        }else if Questions.count > 0 && questionscount < 50{
            QNumber = Int(arc4random_uniform(UInt32(Questions.filter{$0.Question.hasPrefix("ΑΝΘ")}.count)))
            questionscount += 1
            questionLabel.text = Questions.filter{$0.Question.hasPrefix("ΑΝΘ")}[QNumber].Question
    
            self.title = "Ερώτηση: \(Int(questionscount))/50"
            answerNumber = Questions.filter{$0.Question.hasPrefix("ΑΝΘ")}[QNumber].Answer
    
            for i in 0..<buttons.count{
                buttons[i].setTitle(Questions.filter{$0.Question.hasPrefix("ΑΝΘ")}[QNumber].Answers[i], for: UIControlState.normal)
            }
            Questions.remove(at: QNumber)
    
        }else
        {
            let alert = UIAlertController(title: "Σκόρ", message: "Απάντησες σωστά τις \(Int(score)) από τις \(Int(questionscount)) ερωτήσεις! \n \(String(format: "%.0f",(score/questionscount*100))) %", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "Μενού", style: UIAlertActionStyle.default, handler: { action in
                self.navigationController?.popToRootViewController(animated: true)
            }))
            self.present(alert, animated: true, completion: nil)
        }
        Hide()
    }