Math.random() >= 0.5和Math.random() - 0.5有什么区别?

4
我想生成一个长度为n的数组,数组的元素是介于2到32之间的随机整数。我使用了下面这个函数,但我发现17总是返回数组的第一个元素。当我将排序函数改为sort(() => Math.random() - 0.5)时,它就可以正常工作了。
所以我很困惑,Math.random() >= 0.5Math.random() - 0.5有什么区别?这种差异如何影响sort()函数?

const fn = (n) => {
  let arr = [];
  for (let i = 2; i < 33; i++) {
    arr.push(i);
  }
  return arr.sort(() => Math.random() >= 0.5).slice(0, n)
}

2个回答

6
您没有正确使用sort函数,这样会导致结果不可预测、奇怪,并且在不同的浏览器中可能会有所不同。如果您想打乱一个数组,请使用更好的函数
传递给Array.sort()的函数应该接受两个参数x和y,并返回一个负值,如果x < y, 返回0,如果x = y,则返回正值,如果x > y。
在您的第一次尝试中,您使用了sort(() => Math.random() >= 0.5),它返回一个布尔值;这将被转换为0或1。这意味着您的函数告诉排序器,无论您传递的第一个参数是什么,它始终等于或大于您传递的第二个参数。每次调用函数时都会将17作为第二个参数传递;您告诉浏览器它因此小于或等于数组中的其他元素,因此它将被放置在数组的开头。
您的第二次尝试,使用sort(() => Math.random() - 0.5),以相等的概率返回第一个数字大于第二个数字,或反之亦然,这使得洗牌效果更好。但是,由于整个过程的不可靠性,不能保证洗牌在所有浏览器中都能正常工作或特别随机。请使用上面链接的“真实”洗牌算法。
来源:http://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.sort

1
微软因为完全符合这一点而几乎被起诉:http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html - slebetman
TIL。这是一篇非常棒的文章,它真的应该向OP证明不要使用那个函数!感谢提供链接! - Richard Ye
每次调用函数时为什么要将17作为第二个参数传入? - user3077147
这将取决于浏览器如何实现排序。我可以看到它被选为快速排序中的第一个枢轴。或者,由于它在数组的中间,因此可能会因合并排序中的合并步骤而结束,并且可能会与每个其他项进行比较。同样,这完全取决于浏览器的排序实现,您的结果肯定会有所不同。 - Richard Ye

-1
对于 JavaScript 中的 sort 方法,参数是比较函数,需要返回三个值:负数、零、正数,分别代表小于、等于和大于。
如果使用 >= 符号,则只返回布尔值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接