@AlexandraWeather

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

У меня в учебнике такая вот задачка:
"Сделайте функцию, которая параметром будет принимать массив и возвращать случайный элемент этого массива так, чтобы одинаковые элементы не возвращались два раза подряд"
Вот как я пробовала ее решить:
const arr = [1, 255, 639, 9, 7, 8, 5, 4, 2];

const task = (arr) => {
  const len = arr.length;
  let index;
  let curr = -1;
  let prev = -1;
  
  while (curr === prev) {
    index = Math.floor(Math.random() * (len - 1)) + 1;
    curr = arr[index];
  }
  
  prev = curr;
  return curr;
}


Но одинаковые значения все время проскакивают и не по два, а иногда и по три раза
что я делаю не так?
  • Вопрос задан
  • 175 просмотров
Решения вопроса 3
@0x0f80
Вы обнуляете переменную prev при каждом вызове функции. Используйте замыкание
Ответ написан
@historydev Куратор тега JavaScript
Острая аллергия на анимешников
const array = [1, 255, 639, 9, 7, 8, 5, 4, 2];

const randomIndex = arr => Math.round(Math.random() * (arr.length-1));

const randomEl = arr => {
    let index = randomIndex(arr), prev = arr[index];
    return () => {
        do {
          index = randomIndex(arr);
        }
  	while(prev === arr[index]);
        prev = arr[index];
        return arr[index];
    }
}

const getRandomEl = randomEl(array);

for(let i = 0; i < 10; i++) {
    console.log(getRandomEl());
}
Ответ написан
Комментировать
Alexandroppolus
@Alexandroppolus
кодир
(random-размышления с привкусом кольца вычетов)
вариант без дополнительных попыток в случае повторов:

function createRandom(arr) {
    const uniqArr = [...new Set(arr)]; // выкидываем дубликаты из массива

    let size = uniqArr.length;
    let index = -1;

    return () => {
        const rand = Math.floor(Math.random() * size);
        index = (rand + index + 1) % uniqArr.length;
        size = uniqArr.length - 1;
        return uniqArr[index];
    };
}

// использование
const getRand = createRandom([0, 1, 2, 3]);

for (let i = 0; i < 15; ++i) {
    console.log(getRand());
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы