如何改进此功能以测试下划线示例 `_.sample()`

How to improve this function to test Underscore Sample `_.sample()`

设置:

我第一次在一些客户的代码中使用 _.sample(),我想测试它以确保它一次又一次地产生均匀分布的样本。

为了对此进行测试,我创建了以下代码:

(function(arraySize, timesToRun){
  arraySize = arraySize || 10;
  timesToRun = timesToRun || 1000;
  let myArray = Array.apply(null, {length: arraySize}).map(Number.call, Number);
  let resultsArray = Array.apply(null, Array(arraySize)).map(Number.prototype.valueOf,0);
  for (let i = 0; i < timesToRun; i++) {
    var result = _.sample(myArray);
    resultsArray[result]++;
  }
  return resultsArray;
})(10, 1000);

这在我的 Chrome 浏览器中运行完美,得到以下结果:

[93, 112, 97, 87, 97, 107, 97, 104, 105, 101]

正如预期的那样,使用其他输入 (20, 10000) 我们得到:

[646, 663, 641, 749, 648, 686, 642, 631, 663, 688, 691, 639, 672, 663, 678]

所以...就是这样,代码满足了我的需求,完全可以接受。


这是我要找的东西:

解释如下:

如果能回答这三个问题中的 any/all 个,将被接受。

  1. 我不明白 Array.apply(null, {length: arraySize}).map(Number.call, Number); 是如何工作的。具体来说,让我非常困惑的部分是 map 调用中发生的事情:map(Number.call, Number) - 为什么这会产生一个看起来像 [0,1,2,3,4,5,6,7,8,9] 的数组?看到这个问题被分割成单独的问题,我问了这个具体问题
  2. 为什么我们在 map(Number.prototype.valueOf,0) 中需要 Number.prototype.valueOf 我把这个问题交给了一个新的 post
  3. 是否有更好的方法将默认值设置为 arraySizetimesToRun(注意:我在函数调用中放置相同的值只是为了说服 - 我知道这不是必需的。)

请对代码提出任何其他批评,我问这个问题是为了了解更多关于 Javascript 的信息,看看是否可以对该功能进行任何明显的改进。


愿望清单:

也许任何人都可以发表评论,如果他们知道这样做的好方法:

我想找到一种简洁的方法来为该测试创建图形输出。有谁知道一个易于使用的库,以便我可以绘制它。也许对于更多的输入,我们可以获得漂亮的钟形曲线? - Here is a simple way - 我把它放在这里是因为这个问题再次被否决了,但我想为其他想要这样做的人提供信息。


重要提示!

这个问题的格式不正确。我会将这个问题拆分成更小的问题,然后 post 分开。我在阅读后进行了此编辑:https://blog.whosebug.com/2010/09/good-subjective-bad-subjective/

...好吧,我无法关闭这个问题 - 所以我将在下面留下原来的 post。如果有人决定回答这个问题,我仍在寻找这些问题的答案,我会接受。

由于有人抱怨这个问题不是很直接,我创建了其他帖子来获得我正在寻找的答案。这回答了我的主要问题。

答案:

  1. 了解 array.prototype.call() 的工作原理解释了此模式的输出。完整详细的答案可以在这里找到:
  2. 原因在于 array.prototype.map() 的工作方式 - 完整答案在这里:
  3. 是的,从 ES6 开始,有另一种方法可以为 javascript 中的参数设置默认值:

(function(arraySize = 10, timesToRun = 1000){
  let myArray = Array.apply(null, {length: arraySize}).map(Number.call, Number);
  let resultsArray = Array.apply(null, Array(arraySize)).map(Number.prototype.valueOf,0);
  for (let i = 0; i < timesToRun; i++) {
    var result = _.sample(myArray);
    resultsArray[result]++;
  }
  // Turned into console.log() for Whosebug Snippet
  // return resultsArray;
  console.log(resultsArray);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

并且 here is a simple way to set this up graphically 如果有人感兴趣的话。