在iOS中随机显示字符串而不重复

在iOS中随机显示字符串而不重复,ios,swift,random,Ios,Swift,Random,我正在做一个测验应用程序。该应用程序使用.json文件作为问答的“数据库”。这个.json文件如下所示 { "id" : "1", "question": "Earth is a:", "answers": [ "Planet", "Meteor", "Star", "Asteroid" ],

我正在做一个测验应用程序。该应用程序使用.json文件作为问答的“数据库”。这个.json文件如下所示

      {
        "id" : "1",
        "question": "Earth is a:",
             "answers": [
            "Planet",
            "Meteor",
            "Star",
            "Asteroid"
          ],
          "difficulty": "1"
      }
…然后继续问500多个问题

我使用以下代码随机显示问题:

    let randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
    LoadQuestion(randomNumber)
这项工作很好,但因为它随机选择问题,我发现问题重复得太频繁了(尽管我有500多个问题!)

我对此进行了广泛的研究,并认为可能我读得太多了,因为我现在很困惑。我读过关于“播种”,关于保存问题索引,以及尝试使用NSUserDefault

简言之,我如何修改代码以实现以下结果之一:

  • 不重复任何问题,但在所有问题都被问过一次后停止提问
  • 与上面的1类似,但由用户设置问题数量,而不是询问数据库中的所有问题
  • 在所有问题都被先问完之前,不要重复任何问题;或者
  • 不要重复以前回答正确的问题,但可能会重复回答错误的问题
  • 以下是我认为相关的代码位:

        LoadAllQuestionsAndAnswers()
    
        let randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
        LoadQuestion(randomNumber)
    
    
    func LoadAllQuestionsAndAnswers()
    {
        let path = NSBundle.mainBundle().pathForResource("content", ofType: "json")
        let jsonData : NSData = NSData(contentsOfFile: path!)!
        allEntries = (try! NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers)) as! NSArray
        //println(allEntries)
    
    }
    
    
    func LoadQuestion(index : Int)
    {
        let entry : NSDictionary = allEntries.objectAtIndex(index) as! NSDictionary
        let question : NSString = entry.objectForKey("question") as! NSString
        let arr : NSMutableArray = entry.objectForKey("answers") as! NSMutableArray
    
        //println(question)
        //println(arr)
    
        labelQuestion.text = question as String
    
        let indices : [Int] = [0,1,2,3]
        //let newSequence = shuffle(indices)
        let newSequence = indices.shuffle()
        var i : Int = 0
        for(i = 0; i < newSequence.count; i++)
        {
            let index = newSequence[i]
            if(index == 0)
            {
                // we need to store the correct answer index
                currentCorrectAnswerIndex =  i
    
            }
    
            let answer = arr.objectAtIndex(index) as! NSString
            switch(i)
            {
            case 0:
                buttonA.setTitle(answer as String, forState: UIControlState.Normal)
                break;
    
            case 1:
                buttonB.setTitle(answer as String, forState: UIControlState.Normal)
                break;
    
            case 2:
                buttonC.setTitle(answer as String, forState: UIControlState.Normal)
                break;
    
            case 3:
                buttonD.setTitle(answer as String, forState: UIControlState.Normal)
                break;
    
            default:
                break;
            }
    
    
    
        }
        buttonNext.hidden = true
        // we will need to reset the buttons to reenable them
        ResetAnswerButtons()
    
    }
    
    
    
    @IBAction func PressedButtonNext(sender: UIButton) {
        print("button Next pressed")
        let randomNumber = Int(arc4random_uniform(UInt32(allEntries.count)))
        LoadQuestion(randomNumber)
    
    }
    
    LoadAllQuestionsAndAnswers()
    设randomNumber=Int(arc4random_统一(UInt32(allEntries.count)))
    装载问题(随机编号)
    func LoadAllQuestionsAndAnswers()
    {
    让path=NSBundle.mainBundle().pathForResource(“内容”,类型为:“json”)
    让jsonData:NSData=NSData(contentsOfFile:path!)!
    allEntries=(try!NSJSONSerialization.JSONObjectWithData(jsonData,选项:NSJSONReadingOptions.MutableContainers))作为!NSArray
    //println(allEntries)
    }
    func LoadQuestion(索引:Int)
    {
    让条目:NSDictionary=allEntries.objectAtIndex(索引)作为!NSDictionary
    让问题:NSString=entry.objectForKey(“问题”)作为!NSString
    让arr:NSMutableArray=entry.objectForKey(“answers”)作为!NSMutableArray
    //println(问题)
    //println(arr)
    labelQuestion.text=问题作为字符串
    let索引:[Int]=[0,1,2,3]
    //让newSequence=shuffle(索引)
    让newSequence=index.shuffle()
    变量i:Int=0
    对于(i=0;i
    如果我正确理解您的要求:

    • 您希望在视图控制器实例和应用程序启动之间保留随机生成的数字
    • 你永远不想重复任何问题
    实现这一点的快速方法是使用
    NSUserDefaults
    跟踪PRNG中(伪)随机数的顺序和值。通过这种方式,您可以通过重放之前的掷骰子,以正确的顺序将这些问题从池中移除,来实例化实例化实例化时可用问题的数组

    这还允许您将PRNG作为一个黑匣子处理,而不关心种子设定和重播

    此外,确保从当前掷骰子池中删除所有选定的问题

    旁注:您没有遵循命名约定-例如,函数将以小写开头

    为了您自己的利益和可读性,请遵循流行的惯例,至少在与他人共享代码时。更好的是,一直如此

    编辑

    更详细地说:

    • NSUserDefaults
      可以方便地为您保存少量数据。如果你“只想记住一组数字”,那么这就是你要去的地方
    • 假设您的数据保存在一个实例变量中,如下所示:

      var questions : [Question] = // load the questions - carefully, see below.
      
      您可以轻松删除PSNG(pseudo-randomnumberggenerator)选择的问题,如下所示:

      let randomNumber = Int(arc4random_uniform(UInt32(questions.count)))
      questions.removeAtIndex(randomNumber)
      
      因此,下一次掷骰子(例如,调用您的PSNG)保证不会选择已经提出的问题,因为它不再在它从中选择的可用问题池中

    • 这种方法确实需要您以正确的顺序保存所有随机数,以便在实例化新实例时“重播”之前发生的事情(例如,因为应用程序已重新打开)。这就是在最初加载问题并“记住”每个新掷骰子时的位置和作用


    我希望,这涵盖了您以前可能不理解的内容。

    谢谢Jan的建议。这对我来说都是新鲜事,所以你说的大部分内容都像是在读外语,但我会再次尝试研究。如果您有什么可以参考的,甚至是一些代码示例,那就太好了。感谢您对以下命名约定的建议-我甚至不知道函数应该以小写开头,所以我将继续更正我的所有代码