我有一个函数可以从一个名为quizQuestions的数组中获取问题,显示所选择的问题,将其从数组中拼接出来并推送问题并更正新数组的答案,以便稍后在结果屏幕中使用:
// The questions are stored in an array called "quizQuestions"
function makeQuestion()
var randNum:Number = Math.round(1 + (quizQuestions.length - 1) * Math.random());
mc_quiz.question.text = quizQuestions[randNum][0];
answer = quizQuestions[randNum][1];
quizQuestions.splice(randNum,1);
printQuestions.push(new Array(mc_quiz.question.text, answer));
}
它运行良好但不时,问两次问题。您可以继续测试,但结果不会显示信息。实际上,它只显示复制前回答的问题的结果。我已经通过视觉检查和“重复元素查找器”进行了检查,并且阵列中没有重复的问题。
接头是否可以不时执行?你能看到函数中的“bug”吗?可能因为硬问题而发生吗?
提前致谢。
答案 0 :(得分:1)
您的随机数生成不仅在数学上是错误的(即它不会生成真正的随机项),它还会不时生成超出数组边界的数字。为了解释这一点:1+(array.length-1) * Math.random()
将生成大于或等于1的任何数字(这也将导致数组的第一项永远不会被返回,因为数组是基于0的),最多比一小数小于数组的实际长度。如果你Math.round()
得到最高结果,它将向上舍入到下一个最高整数,这又是全长 - 如果你访问array[array.length]
,则会抛出一个错误,这可能是造成错误的原因。你看到的奇怪的行为。
这是一个可能的解决方案:
无论如何, Math.round()
会产生随机数偏差(请参阅@OmerHassans link),因此最好使用int()
或Math.floor()
。此外,Math.random()
定义为0 <= n < 1
,因此它永远不会返回1.因此,您可以将随机索引生成器简化为int(Math.random()*array.length)
=&gt;任何小于数组长度的整数。
然后,splice()
返回已删除项目的数组,以便您可以传递其第一个项目,而不是创建新数组。
function getRandomItem( arr:Array ):* {
var rand:int = Math.random()*arr.length;
return arr.splice( rand, 1 )[0];
}
function makeQuestion():void {
var q:Array = getRandomItem( quizQuestions );
mc_quiz.question.text = q[0];
answer=q[1];
printQuestions[printQuestions.length] = q;
}
仅供参考:在此背景下无关紧要,但将array.push(item)
替换为array[array.length]=item;
可以提高性能。