从源数组中提取随机数直到源数组中没有唯一值的最佳方法是什么?

What's the best way to pull random numbers from source array of numbers untill there is no unique values left in the source array?

我需要创建一个 makeRandom 函数,它接受一个数字范围作为数组,其中第一个数字是范围的开头,第二个是范围内包含该数字的结尾。这个函数的结果应该是一个函数,而调用 returns 是范围内的一个随机数。 returned 的数字必须是唯一的。如果我 运行 出唯一编号,则必须 return null。

它应该像这样工作:

const getRandom = makeRandom([1, 5]);
getRandom() === 3
getRandom() === 4
getRandom() === 5
getRandom() === 2
getRandom() === 1
getRandom() === null
getRandom() === null

所以我尝试了:

function makeRandom(numbers) {
  return () => {
    let randNumber = Math.floor(Math.random() * numbers.length);

    for (let i = 0; i < numbers.length; i++) {
      randNumber += numbers[i];

      if (randNumber === numbers[i]) {
        return true;
      }

      if (randNumber === numers[i].length) {
        return true;
      }
    }

    if (!numbers) {
      return null;
    }
  };
}

但它不起作用。那么最好的方法是什么?

如果数组有长度或 return null.

,您可以添加数组中的所有值并拼接数组

const
    makeRandom = ([min, max]) => {
        const values = [];
        while (min <= max) values.push(min++);
        return () => values.length
            ? values.splice(Math.floor(Math.random() * values.length), 1)[0]
            : null;
    },
    getRandom = makeRandom([1, 5]);

console.log(getRandom());
console.log(getRandom());
console.log(getRandom());
console.log(getRandom());
console.log(getRandom());
console.log(getRandom());
console.log(getRandom());

我会亲自生成数字列表。我会洗牌,这比随机分配好一点。然后我会将它们从阵列中弹出。

// Fisher-Yates shuffle
function shuffle(array) {
  let currentIndex = array.length, temporaryValue, randomIndex;
  while (0 !== currentIndex) {
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }
  return array;
}

// create a range of numbers
function range(size, startAt = 0) {
  return [...Array(size).keys()].map(i => i + startAt);
}

function makeRandom(low, high) {
  const numbers = shuffle(range(high - low + 1, low));
  return function () {
    return numbers.length ? numbers.pop() : null;
  }
}


var myRandom = makeRandom(5,10);
console.log(myRandom());
console.log(myRandom());
console.log(myRandom());
console.log(myRandom());
console.log(myRandom());
console.log(myRandom());
console.log(myRandom());
console.log(myRandom());