从列表中随机挑选项目,每个都有不同的机会

时间:2017-06-08 13:58:21

标签: javascript arrays random

我想写一个简单的函数,允许从列表中滚动随机项,我用这段代码做了:

this.resources = [false, 'nitrogen', 'silicon', 'cobalt', 'magnesium'];

this.assign_resource = function() {
    var index = tools.rnd(0, this.resources.length - 1);
    return this.resources[index];
};

但它打得不好,所以我想把它改成不同的系统,允许一个项目列表(包括空的一个),它随机选择一个,但每个都有不同的机会(例如这个有10个%,这个有20%)。也许有人可以帮助我完成这种功能。

已编辑-----

例如,这可能是新列表:

this.resources = [
    { type: 'empty', chance: 30 },
    { type: 'nitrogen', chance: 10 },
    { type: 'silicon', chance: 20 },
    { type: 'cobalt', chance: 30 },
    { type: 'magnesium', chance: 10 }
];

现在如何使用它来使其正常发生?

已编辑2 -----

我正在尝试使用数学找出做得好的编程解决方案而不是简单地复制数组中的项目,this主题中提供的答案只是解决问题。

5 个答案:

答案 0 :(得分:3)

我通过让一个有可能成为结果的对象数组来解决它,总计1.0,然后选择0到1之间的随机数,然后迭代资源并检查是否将其添加到累计总数中包括您的随机数。



var resources = [
  { resource: false, chance: 0.2 },
  { resource: 'nitrogen', chance: 0.1 },
  { resource: 'silicon', chance: 0.2 },
  { resource: 'cobalt', chance: 0.45 },
  { resource: 'mangesium', chance: 0.05 }    
];

function get_result(resouceList) {
  //get our random from 0 to 1
  var rnd = Math.random();
  
  //initialise our cumulative percentage
  var cumulativeChance = 0;
  //iterate over our resources
  for (var i = 0; i < resouceList.length; i++) {
    
    //include current resource
    cumulativeChance += resouceList[i].chance;
    
    if (rnd < cumulativeChance)
      return resouceList[i].resource;
  }
  
  return false;  
}

//test
console.log(get_result(resources));
console.log(get_result(resources));
console.log(get_result(resources));
console.log(get_result(resources));
console.log(get_result(resources));
&#13;
&#13;
&#13;

答案 1 :(得分:1)

你可以这样做。

多次创建具有相同值的数组会使其更有可能被选中。

&#13;
&#13;
var resources = [{
    type: 'empty',
    chance: 30
  },
  {
    type: 'nitrogen',
    chance: 10
  },
  {
    type: 'silicon',
    chance: 20
  },
  {
    type: 'cobalt',
    chance: 30
  },
  {
    type: 'magnesium',
    chance: 10
  }
];


function GetRandom(list) {
  var array = [];
  for (var i = 0; i < list.length; i++) {
    var item = list[i];
    var chance = item.chance / 10;
    for (var j = 0; j < chance; j++) {
      array.push(item.type);
    }
  }
  var idx = Math.floor(Math.random() * array.length);
  return array[idx];

}

console.log(GetRandom(resources))
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 2 :(得分:1)

我会设置它,以便只有实际资源在你的数组中,并且如果随机滚动落在那些之外就会发生“空”。

this.resources = [
    { type: 'nitrogen', chance: 10 },
    { type: 'silicon', chance: 20 },
    { type: 'cobalt', chance: 30 },
    { type: 'magnesium', chance: 10 }
];

this.assign_resource = function() {
  var rnd = Math.random();
  var acc = 0;
  for (var i=0, r; r = this.resources[i]; i++) {
    acc += r.chance / 100;
    if (rnd < acc) return r.type;
  }
  // rnd wasn't less than acc, so no resource was found
  return 'empty';
}

答案 3 :(得分:1)

这就是我实施解决方案的方式。 第1步:积累所有可能的机会 第2步:选择与总机会成比例的随机值 第3步:遍历资源以查看随机值属于哪个部分。

var resources = [
    { type: 'empty', chance: 30 },
    { type: 'nitrogen', chance: 10 },
    { type: 'silicon', chance: 20 },
    { type: 'cobalt', chance: 30 },
    { type: 'magnesium', chance: 10 }
];

function solution(resources) {
  let chanceTotal = resources.reduce((acc, val) => { acc += val.chance ; return acc;}, 0);
  let randomVal = parseInt(Math.random() * chanceTotal);
  let chanceAcc = 0;
  let ans;
  resources.forEach(r => {
    chanceAcc += r.chance;
    if (chanceAcc > randomVal && !ans) {
      ans = r;
    }
  });
  return ans;
}

console.log(solution(resources));

答案 4 :(得分:1)

这是另一种实现方式。

var res = [
    ["empty", 3],
    ["nitrogen", 1],
    ["silicon", 2],
    ["cobalt", 3],
    ["magnesium", 1]
];
var flat = [];
var item;
for(var i = 0, l = res.length; i < l; i++) {
    item = Array(res[i][1]+1).join(i+",");
    item = item.substr(0, item.length-1);
    flat.push(item);
}
flat = flat.join(",").split(",");

function get_random_item() {
    var ridx = Math.floor(Math.random() * (flat.length));
    return res[flat[ridx]][0];
}

var pick;
for(var p = 0; p < 50; p++) {
    pick = get_random_item();
    console.log(p, pick);
}