仅对数组的 returns 部分进行混洗
Shuffling an array only returns part of the array
我写了一个函数来打乱数组的元素。
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;
}
由于某种原因,该函数只returns一半的数组元素。如果将一个包含 7 个元素的数组传递给它,则它 returns 4 个元素。同样,如果返回一个有8个元素的数组。
我哪里错了?
只需将数组的长度存储在一个变量中,然后在 for-loop header 而不是 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));
请注意,这只是您问题的快速解决方案,并非推荐的解决方案。
然后回答你的问题 - 为什么当你有 4 个项目的数组时,将返回只有 2 个项目的数组 - 让我们看看你在每次迭代中减少数组长度的循环的执行.
iteration; i; arr.length; i < arr.length
1 0 4 true
2 1 3 true
3 2 2 false
有很多 Q&A on Whosebug 提供了正确有效的算法。在您的代码中,循环变量递增到 arr.length
,但在每次迭代中,您将 length
减少为 splice
,因此总的来说,i
只会 运行 大约是原始长度的一半,因此你的函数 returns 是一个大约输入大小一半的数组。
快速修复:使用 while
循环代替 for
循环:
while (arr.length) {
可选:为了完整保留输入数组,请替换以下无用的赋值:
var oldarr = arr;
...带有复制语句:
arr = arr.slice();
我写了一个函数来打乱数组的元素。
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;
}
由于某种原因,该函数只returns一半的数组元素。如果将一个包含 7 个元素的数组传递给它,则它 returns 4 个元素。同样,如果返回一个有8个元素的数组。
我哪里错了?
只需将数组的长度存储在一个变量中,然后在 for-loop header 而不是 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));
请注意,这只是您问题的快速解决方案,并非推荐的解决方案。
然后回答你的问题 - 为什么当你有 4 个项目的数组时,将返回只有 2 个项目的数组 - 让我们看看你在每次迭代中减少数组长度的循环的执行.
iteration; i; arr.length; i < arr.length
1 0 4 true
2 1 3 true
3 2 2 false
有很多 Q&A on Whosebug 提供了正确有效的算法。在您的代码中,循环变量递增到 arr.length
,但在每次迭代中,您将 length
减少为 splice
,因此总的来说,i
只会 运行 大约是原始长度的一半,因此你的函数 returns 是一个大约输入大小一半的数组。
快速修复:使用 while
循环代替 for
循环:
while (arr.length) {
可选:为了完整保留输入数组,请替换以下无用的赋值:
var oldarr = arr;
...带有复制语句:
arr = arr.slice();