我的洗牌程序有什么问题?

What is wrong with my shuffling program?

我在下面写了一个洗牌程序并运行它通过"Will It Shuffle?"。结果似乎表明它正在控制台中工作;它正在改组数组。但是该网站向我显示了一个全红框,让我觉得我的代码有问题,但我没有看到。

function shuffle (array) {
    var arr = [],
        length = array.length,
        el;

    while (length > 0) {
      var randomEl = Math.floor(Math.random() * (length - 0) - 0);
      if (length > 1) {
        el = array.splice(randomEl,1);
      } else {
        el = array.splice(0,1);
      }
        arr.push(el[0]);
        length -= 1;
    }

  return arr;
}

该页面忽略函数的返回值,因为它需要 in-place 排序。

如果您在代码末尾添加它,它会按预期工作:

array.push(...arr);

您也可以直接就地进行:

function shuffle (array) {
  var length = array.length;
  while (length) {
    var randomEl = Math.floor(Math.random() * length);
    var el = array.splice(randomEl, 1);
    array.push(el[0]);
    --length;
  }
}

他们改变数组,你不改变数组。

您需要更改原始数组,而不是return一个新数组。

function shuffle (array) {
    var arr = [],
        length = array.length,
        el;

    while (length > 0) {
      var randomEl = Math.floor(Math.random() * (length - 0) - 0);
      if (length > 1) {
        el = array.splice(randomEl,1);
      } else {
        el = array.splice(0,1);
      }
        arr.push(el[0]);
        length -= 1;
    }

  //replace array with the new items 
  //it is like using concat, but does not produce a new array, 
  //just appends it to the original which has zero items in it.
  Array.prototype.push.apply(array, arr);  



}

你正在做的是创建一个新的数组,其中的元素随机排列。

但是,如果您返回查看传入的数组,您会发现它没有被打乱,而是被清空了。显然,这不是 "Will it Shuffle?" 要求你做的。

splice() 和 push() 都会改变您调用这些方法的数组。

为了回答您关于 .push(...arr) 的问题,javascript 中的省略号是最新版本 EcmaScript 2015 中的一项功能。它是 "spread operator"。

当您使用 "spread" 数组调用函数时,就像使用数组的内容作为单独的参数调用函数一样。例如,

array.push(...[1,2,3])

等同于调用

array.push(1,2,3)

push() 可以向数组添加任意数量的逗号分隔参数。因此,在使用循环拼接清空数组参数后,您可以使用扩展运算符将新创建的 arr 的内容推送到空数组。