如何改进此函数来测试Underscore Sample`_.sample()`

时间:2016-06-17 17:19:47

标签: javascript arrays underscore.js random-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]

所以......就是这样,代码完成了我需要的东西,完全可以接受。

以下是我要找的内容:

以下说明:

如果能够回答这三个问题中的任何一个问题,将接受答案。

  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]的数组?看到这个问题正在被分成单独的问题,我已经问过这个具体的问题elsewhere
  2. 我们为什么Number.prototype.valueOf需要map(Number.prototype.valueOf,0)我将这个问题归结为一个新帖子this has been answered here
  3. 有更好的方法可以将默认值设置为arraySizetimesToRun吗? (注意:我在函数调用中使用相同的值只是为了说服 - 我知道这不是必需的。)
  4. 请对代码做出任何其他批评,我会问这个问题以了解有关Javascript的更多信息,并了解是否可以对此功能进行任何明显的改进。

    愿望清单:

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

    我想找到一种干净整洁的方法来为这个测试创建图形输出。有谁知道一个简单的库使用,以便我可以绘制这个图。也许为了更多的输入,我们可以得到一个漂亮的钟形曲 - Here is a simple way - 我把它放在这里内联,因为这个问题一直被低估了,但是我想给其他想要这样做的人提供信息。

    重要提示!

    此问题格式不正确 。我将把这个问题分成小问题并分别发布。我在阅读完{Chid}后进行了此编辑:http://blog.stackoverflow.com/2010/09/good-subjective-bad-subjective/

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

1 个答案:

答案 0 :(得分:0)

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

的答案:

  1. 了解array.prototype.call()的工作原理解释了此模式的输出。可在此处找到完整详细的答案:Mapping Array in Javascript with sequential numbers
  2. 原因是因为array.prototype.map()的工作方式 - 完整答案:Why do we use Number.prototype.valueOf inside of a map() function
  3. 是的,从ES6开始,还有另一种方法可以在javascript中为参数设置默认值:
  4. &#13;
    &#13;
    (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 StackOverflow Snippet
      // return resultsArray;
      console.log(resultsArray);
    })();
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    &#13;
    &#13;
    &#13;

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