我编写了一个对数组元素进行混洗的函数。
function shuffle(arr) {
var newarr = [];
var oldarr = arr;
for(var i = 0; i < arr.length; i++) {
var index = Math.floor(Math.random() * arr.length);
newarr.push(arr[index]);
arr.splice(index, 1);
}
return newarr;
}
由于某种原因,该函数只返回一半的数组元素。如果向其传递了7个元素的数组,则返回4个元素。同样,如果返回一个包含8个元素的数组。
我哪里出错了?
答案 0 :(得分:1)
只需将数组的长度存储在变量中,并将其用于for循环标头而不是arr.length
。而且var oldarr = arr
行在您的代码中没有任何作用。
const arr = [1, 2, 3, 4];
function shuffle(arr) {
var newarr = [];
const length = arr.length;
for (var i = 0; i < length; i++) {
var index = Math.floor(Math.random() * arr.length);
newarr.push(arr[index]);
arr.splice(index, 1);
}
return newarr;
}
console.log(shuffle(arr));
&#13;
请注意,这只是您问题的快速解决方案,而不是推荐的解决方案。
并回答你的问题 - 为什么当你有4个项目的数组时,只会返回只包含2个项目的数组 - 让我们看一下你在减少数组长度的那个循环的执行情况每次迭代。
iteration; i; arr.length; i < arr.length
1 0 4 true
2 1 3 true
3 2 2 false
答案 1 :(得分:1)
有许多Q&A on StackOverflow提供了正确有效的算法。在您的代码中,循环变量最多递增到arr.length
,但在每次迭代中,您使用length
减少splice
,因此总共i
只会运行到大约一半原始长度,结果你的函数返回一个大约一半输入大小的数组。
快速修复:使用for
循环代替while
循环:
while (arr.length) {
可选:为了使输入数组保持完整,请替换以下无用的赋值:
var oldarr = arr;
...带有复制声明:
arr = arr.slice();