在iOS中随机显示字符串而不重复
我正在做一个测验应用程序。该应用程序使用.json文件作为问答的“数据库”。这个.json文件如下所示在iOS中随机显示字符串而不重复,ios,swift,random,Ios,Swift,Random,我正在做一个测验应用程序。该应用程序使用.json文件作为问答的“数据库”。这个.json文件如下所示 { "id" : "1", "question": "Earth is a:", "answers": [ "Planet", "Meteor", "Star", "Asteroid" ],
{
"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
简言之,我如何修改代码以实现以下结果之一:
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
- 假设您的数据保存在一个实例变量中,如下所示:
您可以轻松删除PSNG(pseudo-randomnumberggenerator)选择的问题,如下所示:var questions : [Question] = // load the questions - carefully, see below.
因此,下一次掷骰子(例如,调用您的PSNG)保证不会选择已经提出的问题,因为它不再在它从中选择的可用问题池中let randomNumber = Int(arc4random_uniform(UInt32(questions.count))) questions.removeAtIndex(randomNumber)
- 这种方法确实需要您以正确的顺序保存所有随机数,以便在实例化新实例时“重播”之前发生的事情(例如,因为应用程序已重新打开)。这就是在最初加载问题并“记住”每个新掷骰子时的位置和作用
我希望,这涵盖了您以前可能不理解的内容。谢谢Jan的建议。这对我来说都是新鲜事,所以你说的大部分内容都像是在读外语,但我会再次尝试研究。如果您有什么可以参考的,甚至是一些代码示例,那就太好了。感谢您对以下命名约定的建议-我甚至不知道函数应该以小写开头,所以我将继续更正我的所有代码