对数组进行混洗只会返回数组的一部分

时间:2018-06-07 18:32:39

标签: javascript arrays shuffle

我编写了一个对数组元素进行混洗的函数。

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个元素的数组。

我哪里出错了?

2 个答案:

答案 0 :(得分:1)

只需将数组的长度存储在变量中,并将其用于for循环标头而不是arr.length。而且var oldarr = arr行在您的代码中没有任何作用。

&#13;
&#13;
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;
&#13;
&#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();