Math.random永远不会产生与其他Math.random相同的数字

时间:2018-07-08 15:53:12

标签: javascript

我有4个Math.random生成器。每次从数组中选择X个对象中的1个。

  var randomItem1 = projects[Math.floor(Math.random()*projects.length)];
  var randomItem2 = projects[Math.floor(Math.random()*projects.length)];
  var randomItem3 = projects[Math.floor(Math.random()*projects.length)];
  var randomItem4 = projects[Math.floor(Math.random()*projects.length)];

如何编写防止Math.random生成与其他Math.random生成器相同的数字的函数。

我的猜测: 创建一个循环var randomItem 1 till 4的循环。如果发现1个或多个输出相同,则会为1个或多个重复输出重新生成新输出。

还有其他建议吗?

编辑:这是针对网站的。

2 个答案:

答案 0 :(得分:1)

感谢有趣的问题。我总是使用一个库来处理这种事情,所以弄清楚它很有趣。

var projects
var randomProjects

function getRandomProjects(projects, sampleSize) {
  var projectsClone = projects.slice();
  var randomItems = [];
  while (sampleSize--) {
    randomItems.push(
      projectsClone.splice(Math.floor(Math.random()*projectsClone.length), 1)[0]
    );
  }
  return randomItems;
}

projects = ['1st project', '2nd project', '3rd project', '4th project', '5th project', '6th project'];
randomProjects = getRandomProjects(projects, 4);

randomProjects.forEach(function(randomProject) {
  console.log(randomProject);
});

projectsClone.splice(...)projectsClone中删除一个随机项目,并将其作为单个项目返回到数组([<project>])中。因此,在循环的下一次迭代中,无法再选择值(<project>)。

但是,如果您在生产代码中使用库,我建议您使用库。例如losdash's _.sampleSize(projects, 4)

答案 1 :(得分:1)

更新

删除了不需要的部分,例如 Setfor循环,并添加了splice()。由于splice(),此函数将使原始数组发生变化。在连续的有序数字数组上使用splice()(即使在改组后)也可以保证一组唯一的数字。


/**
 * genRan(quantity, length)
 *
 * Need a given amount of unique random numbers.
 *
 * Given a number for how many random numbers are to be returned (@quantity) and a 
 * number that represents the range of consecutive numbers to extract the random 
 * numbers from (@length), this function will:
 *  - generate a full array of numbers with the length of @length
 *  - use shuffle() to shuffle the array to provide an array of randomly ordered numbers 
 *  - splices the first @quantity numbers of the shuffled array
 *  - returns new array of unique random numbers
 *
 * @param {Number} quantity      length of returned array.
 * @param {Number} length        length of an array of numbers. 
 * 
 * @return {Array} An array of unique random numbers.
 */


演示

在演示中评论的详细信息

var qty = 4
var len = 100;

function genRan(quantity, length) {
  // Ensure that quantity is never greater than length
  if (quantity > length) {
    quantity = length;
  }
  // Create an array of consecutive numbers from 1 to N
  var array = Array.from({
    length: length
  }, (value, key = 0) => key + 1);
  // Run shuffle get the returned shuffled array
  var shuffled = shuffle(array);
  // return an array of N (quantity) random numbers 
  return shuffled.splice(0, quantity);
}

console.log(genRan(qty, len));

/* shuffle utility 
|| Uses Fisher-Yates algorithm
*/
function shuffle(array) {
  var i = 0;
  var j = 0;
  var temp = null;
  for (i = array.length - 1; i > 0; i -= 1) {
    j = Math.floor(Math.random() * (i + 1))
    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}