Как случайно выбрать элемент из массива, который не был выбран ранее в JavaScript? - PullRequest
0 голосов
/ 23 марта 2020

Я хочу запустить функцию, которая каждый раз случайным образом выбирает элемент из массива, который не был выбран ранее. И если все элементы были выбраны, я хочу сбросить используемые элементы и начать с начала.

Надеюсь, что это имеет смысл.

У меня уже есть функция, которая выбирает случайный элемент из массива , Но я также не хочу, чтобы он выбирал элементы, которые были выбраны ранее, если все элементы не были уже выбраны.

Вот что я получил (кредит @Kelly):

var item = items[Math.floor(Math.random() * items.length)]

Ответы [ 3 ]

3 голосов
/ 23 марта 2020

Вы можете попробовать что-то вроде этого:

Идея

  • Создать вспомогательную функцию, которая принимает массив и возвращает вам случайное значение.
  • Внутри этого массива , поддерживать 2 массива, выбор и данные.
  • В каждой итерации удаляйте 1 элемент из data и помещайте его в chosenItems
  • Как только длина data достигнет 0, установите chosenItems или originalArray как данные и повторите процесс.

Преимущество этого подхода будет,

  • Вам не нужно поддерживать и передавать переменную массива.
  • Это может быть сделал generi c и использовал несколько раз.

function randomize(arr) {
  let data = [...arr];
  let chosenItems = [];

  function getRandomValue() {
    if (data.length === 0) {
      data = chosenItems;
      chosenItems = [];
    }
    const index = Math.floor(Math.random() * data.length);
    const choice = data.splice(index, 1)[0];

    chosenItems.push(choice);
    return choice;
  }
  
  return {
    randomItem: getRandomValue
  }
}

const dummyData = [ 1,2,3,4,5 ];

const randomizeData = randomize(dummyData);

for (let i = 0; i< 10; i++) {
  console.log(randomizeData.randomItem())
}
2 голосов
/ 23 марта 2020

Одним из возможных способов является простое хождение.

Сначала получите список, например, 500 предметов. Получите следующее простое число, которое больше 500. Здесь 503. Выберите случайное начальное число. Это начальное число - это любое число, которое является постоянным для пользователя.

var prime = 503;
var list = ["item1", "item2", ... "item500"];

function pick_nth(seed, n, p, l) {
    if(!n) return l[seed % p];
    return pick_nth((seed + l.length) % p, n - 1, l);
}

Собрать n-й элемент из списка очень просто. Например:

pick_nth(seed, 0, prime, list);  // first item
pick_nth(seed, 1, prime, list);  // second item
...
pick_nth(seed, 499, prime, list);  // 500th item

Порядок возвращаемых предметов переставляется семенем.

2 голосов
/ 23 марта 2020

Самый простой способ справиться с этим:

function shuffle(array) {
  var 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;
}


var items = ["alpha", "beta", "gamma", "delta", "epsilon"];
var index = Infinity;

function start() {
  console.log("----- shuffling -----")
  shuffle(items);
  index = 0;
}

function nextItem() {
  if (index >= items.length) {
    //re-start
    start()
  }
  
  //return current index and increment
  return items[index++];
}

document.getElementById("click_me")
  .addEventListener("click", function() {
    console.log(nextItem())
  })
<button id="click_me">Next random</button>

Это также можно преобразовать в функцию генератора

function shuffle(array) {
  var 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;
}

function* random(array) {
  let index = Infinity;
  const items = array.slice(); //take a copy of the array;
  
  while(true) {
    if (index >= array.length) {
      console.log("----- shuffling -----")
      shuffle(items);
      index = 0;
    }
    
    yield items[index++];
  }
}


var items = ["alpha", "beta", "gamma", "delta", "epsilon"];

//start the generator
const generateRandom = random(items);

document.getElementById("click_me")
  .addEventListener("click", function() {
    console.log(generateRandom.next().value)
  })
<button id="click_me">Next random</button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...