Как лучше всего извлекать случайные числа из исходного массива чисел до тех пор, пока в исходном массиве не останется уникальных значений?

Мне нужно создать функцию makeRandom, которая принимает диапазон чисел в виде массива, где первое число является началом диапазона, второе — концом, включающим это число в диапазон. Результатом этой функции должна быть функция, а вызов возвращает случайное число из диапазона. Возвращаемые числа должны быть уникальными. Если у меня закончатся уникальные номера, я должен вернуть ноль.

Это должно работать так:

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;
    }
  };
}

Но это не работает. Итак, как лучше всего это сделать?

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
140
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете добавить все значения в массив и соединить массив, если массив имеет длину или возврат 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.info(getRandom());
console.info(getRandom());
console.info(getRandom());
console.info(getRandom());
console.info(getRandom());
console.info(getRandom());
console.info(getRandom());

Большое спасибо за ответ!

Viktor Russe 23.12.2020 18:19

Я бы лично сгенерировал список чисел. Я бы перетасовал их, что немного лучше, чем случайное распределение. Затем я бы вытащил их из массива.

// 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.info(myRandom());
console.info(myRandom());
console.info(myRandom());
console.info(myRandom());
console.info(myRandom());
console.info(myRandom());
console.info(myRandom());
console.info(myRandom());

Другие вопросы по теме