这个W3Schools代码如何使用.sort()改组数组? [英] How does this W3Schools code for shuffling an array with .sort() work?
问题描述
此代码段来自 w3schools JavaScript部分。我想找出什么
This code snippet is from w3schools JavaScript section. I am trying to figure out what
points.sort( function(a, b) {
return 0.5 - Math.random()
});
来自下面的代码。我知道它试图对存储在数组中的数字进行随机排序,称为点,但我不明白如何用返回0.5 - Math.random()
。
from the code below does. I understand it is trying to perform a random sort on the numbers stored in the array called points, but I don't understand how it is achieved with return 0.5 - Math.random()
.
我知道random返回0到1之间的数字(不包括1)。
我认为从那个数字中减去0.5,但我不确定从这里发生了什么。你能不能给我一步一步的解释?
I know that random returns a number between 0 and 1 (not including 1). I supposed that 0.5 is then subtracted from that number, but I am not sure what happens from here. Could you kindly give me a step by step explanation?
<!DOCTYPE html>
<html>
<body>
<p>Click the button (again and again) to sort the array in random order.</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
var points = [40, 100, 1, 5, 25, 10];
document.getElementById("demo").innerHTML = points;
function myFunction() {
points.sort(function(a, b){return 0.5 - Math.random()});
document.getElementById("demo").innerHTML = points;
}
</script>
</body>
推荐答案
将回调传递给返回随机值的Array#sort()
是一个坏主意; ECMAScript规范不保证在这种情况下会发生什么。根据 MDN :
Passing a callback to Array#sort()
that returns a random value is a bad idea; the ECMAScript spec provides no guarantees about what will happen in that case. Per MDN:
compareFunction(a,b)
在给定特定的一对时,必须始终返回相同的值元素a和b作为它的两个参数。如果返回不一致的结果,则排序顺序未定义。
compareFunction(a, b)
must always return the same value when given a specific pair of elements a and b as its two arguments. If inconsistent results are returned then the sort order is undefined.
并且每规范本身:
如果 comparefn 不是未定义,并且不是此数组元素的一致比较函数(见下文),则排序顺序是实现定义的。
If comparefn is not undefined and is not a consistent comparison function for the elements of this array (see below), the sort order is implementation-defined.
该问题的W3Schools代码明显被破坏;它不会公平地改变阵列,至少在Chrome中是这样。让我们尝试运行它一百万次并计算shuffling后每个值出现在数组中最终位置的频率:
The W3Schools code from the question is demonstrably broken; it doesn't shuffle the array fairly, at least in Chrome. Let's try running it a million times and counting how often each value shows up in the final position in the array after "shuffling":
function shuffleAndTakeLastElement() {
var points = [40, 100, 1, 5, 25, 10];
return points.sort(function(a, b){return 0.5 - Math.random()})[5];
}
results = {};
for (var point of [40, 100, 1, 5, 25, 10]) results[point] = 0;
for (var i = 0; i < 1000000; i++) results[shuffleAndTakeLastElement()]++;
console.log(results);
我在Chrome中获得以下数量:
I get the following counts in Chrome:
{1: 62622, 5: 125160, 10: 500667, 25: 249340, 40: 31057, 100: 31154}
注意数字10在阵列结束位置结束的可能性大约是数字40或100的16倍。这不是一个公平的洗牌!
Notice how the number 10 is around 16 times more likely to end up in the end position of the array than the numbers 40 or 100 are. This ain't a fair shuffle!
从这个故事中吸取一些道德:
A few morals to draw from this story:
- 您应该运行大量测试并查看结果,以帮助确认任何随机性算法是否公平。
- 即使您'很容易意外编写偏差算法'从公平的随机来源开始。
- 对于洗牌阵列,请使用 Lodash的
_ .shuffle
方法或来自如何使用的方法之一随机化(随机播放)一个JavaScript数组?。 - 永远不要相信你在W3School上读到的任何东西,因为它们很糟糕并且充满了错误。
- You should run a large number of tests and look at the results to help confirm whether any randomness algorithm is fair.
- It's easy to accidentally write a biased algorithm even if you're starting with a fair source of randomness.
- For shuffling arrays, use Lodash's
_.shuffle
method or one of the approaches from How to randomize (shuffle) a JavaScript array?. - Never trust anything you read on W3Schools, because they suck and are riddled with errors.
这篇关于这个W3Schools代码如何使用.sort()改组数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!