使用Javascript从数组中选择随机形状

时间:2015-04-22 22:57:09

标签: javascript arrays random underscore.js

我想从数组中选择两到三个形状,但我不能。我试过这段代码:

var range = _.sample(shapes, 2);

此代码运行但不是随机的。

var range = shapes.length-2 * Math.random();

2 个答案:

答案 0 :(得分:1)

这将从数组中获得1个随机元素

var shape = shapes[Math.floor(Math.random() * shapes.length)];

您可以将其转换为使其更容易使用的功能

function sample(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

现在获得多个随机形状更容易

var shape1 = sample(shapes);
var shape2 = sample(shapes);

但是,在上面的示例中,shape1shape2可能是相同的结果。想想掷骰子:两种结果都可能是4

也许这不是我们想要的。也许我们想要的更像是数字抽奖,数字1-50存在于一个桶中,一旦从桶中删除一个数字,就不可能再次选择它。

要做到这一点,我们必须稍微调整一下这个功能

function sample(arr, count) {
  // default sample size of 1
  if (!count) count = 1;

  // create a copy of the original array
  var copy = arr.slice(0);

  // init samples with empty array
  var samples = [];

  // use a loop to sample n-items
  for (var i=0; i<count; i++) {
    // get the index of a random item
    var idx  = Math.floor(Math.random() * copy.length);

    // remove it from the copy of our array,
    // and add it to the samples result
    samples = samples.concat(copy.splice(idx, 1));
  }

  // return the samples
  return samples;
}

现在你可以看到它永远不会显示重复的

var letters = ["a", "b", "c", "d", "e"];
sample(letters, 3); // ["e", "c", "b"]
sample(letters, 3); // ["e", "a", "d"]
sample(letters, 3); // ["c", "a", "b"]

我们可以对此代码进行有用的调整。请考虑以下事项:

从甲板上随机抽取2张扑克牌,我们可以用两种方式做到这一点

  1. 从排序/未分类甲板的2个随机位置挑选2张牌
  2. 将牌组洗牌,拿上2张牌
  3. 到目前为止,我们编写的sample函数使用的方法更像#1 。但是,如果我们使用#2 这样的方法编写它,我们可以免费获得一个数组混洗功能!酷!

    让我们看看它会是什么样子

    function random(x) {
      return Math.floor(Math.random() * x);
    }
    
    function shuffle(arr) {
      var copy = arr.slice(0);
      return arr.reduce(function(shuffled, elem) {
        var idx = random(copy.length);
        return shuffled.concat(copy.splice(idx, 1));
      }, []);
    }
    
    function sample(arr, n) {
      return shuffle(arr).slice(0, n || 1);
    }
    

    现在,我们已经达到了原定目标并获得了可重复使用的奖励功能randomshuffle,这是将sample写为高阶程序 ^的副作用。 ^

答案 1 :(得分:1)

更新问题似乎与underscore.js有关,而不是一般的数组,所以这里有一个小更新 -

您似乎正在正确使用_.sample()调用,但是当您指定示例值&gt;时,您还需要将结果用作数组。 1:

var shapes = ['circle','star','square','hexagon','triangle','polygon'];
var range = _.sample(shapes, 2);  // => ["square", "triangle"]; (example result)

因此无需使用Math.random()来选择任何项目,因为现在随机选择项目。只需迭代数组即可使用每个索引的实际值。

示例

... other code ...

for(var i = 0, shape; shape = range[i]; i++) {  // will loop through the range array

    switch(shape) {                             // current item
        case "square":                          // (not 0 etc. as in the original code)
            ... code for square here...
            break;

        case "triangle":
            ... code for triangle here...
            break;

        ... etc. ...
    }
} 

Old answer