AS3 / Arrays:“拼接”后无法复制

时间:2013-09-08 05:00:44

标签: arrays actionscript-3 flash runtime-error splice

我有一个函数可以从一个名为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”吗?可能因为硬问题而发生吗?

提前致谢。

1 个答案:

答案 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;可以提高性能。