@schwabsergey

JS(jQuery) Как получить случайный элемент массива без повторений?

Нужна функция возвращающая значение случайного элемента массива, но не повторяющегося.
Например, есть массив
var RGBColorsArr = ['rgb(255,255,0)', 'rgb(255,0,0)', 'rgb(51,0,0)', 'rgb(255,0,102)', 'rgb(0,0,51)', 'rgb(0,0,255)', 'rgb(102,0,255)', 'rgb(0,255,255)', 'rgb(51,51,0)', 'rgb(0,0,0)', 'rgb(0,255,0)', 'rgb(0,51,0)'];

содержит 12 цветов в формате RGB.
Получить случайное значение не трудно (генерирую случайный индекс и записываю его значение в переменную):
var getRandomArrIndex = Math.floor( (Math.random() * RGBColorsArr.length) + 0);
var getColor = RGBColorsArr[getRandomArrIndex];

Чтобы следующее значение не повторялось, решил , что можно удалять из массива по индексу уже полученное значение и выбирать рандомно из оставшихся.
НО! Как это можно закольцевать при N-ом вызове функции. Чтобы после удаления всех элементов массива, вернуться к его первоначальному варианту и повторять процедуру.
  • Вопрос задан
  • 4794 просмотра
Пригласить эксперта
Ответы на вопрос 2
sfi0zy
@sfi0zy Куратор тега JavaScript
Creative frontend developer
В общем случае можно генерировать случайную перестановку для множества из N элементов (в вашем случае 12):
let getRandomPermutation = (n) => {
    let arr = Array.from(Array(n).keys());
    
    for (let i = (n - 1); i > 0; i--) {
        let j = Math.floor(Math.random() * i);
        
        [arr[i], arr[j]] = [arr[j], arr[i]];
    }
    
    return arr;
}


И затем:
let permutation = getRandomPermutation(colors.length);
let temp = colors.slice();

for (let i = 0; i < colors.length; i++) {
    colors[i] = temp[permutation[i]];
}


У вас получается отсортированный в случайном порядке массив цветов. Если нужно начать сначала - генерируете перестановку заново и круг замыкается. Разумеется можно не генерировать перестановку отдельно, а сразу сортировать нужный массив - здесь я разделил для наглядности.

codepen.io/sfi0zy/pen/yVOMmK?editors=0012
Ответ написан
Комментировать
werty1001
@werty1001
undefined
var randomColor = {
    list: [
        'rgb(255,255,0)',
        'rgb(255,0,0)',
        'rgb(0,255,0)',
        'rgb(0,51,0)'
    ],
    already: [],
    random: function () {
        return this.list[Math.floor(Math.random() * this.list.length)];
    },
    get: function () {

        var color = this.random();

        if (this.already.length >= this.list.length) {
            this.already = [];
            return color;
        }

        if (this.already.indexOf(color) !== -1) {
            return this.get();
        } else {
            this.already.push(color);
            return color;
        }

    }
};

Живой пример тык
Ответ написан
Ваш ответ на вопрос

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

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