S
S
schwabsergey2016-11-12 20:11:44
JavaScript
schwabsergey, 2016-11-12 20:11:44

JS(jQuery) How to get a random element of an array without repeating?

We need a function that returns the value of a random array element, but not a repeating one.
For example, there is an array

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)'];

contains 12 colors in RGB format.
Getting a random value is not difficult (I generate a random index and write its value to a variable):
var getRandomArrIndex = Math.floor( (Math.random() * RGBColorsArr.length) + 0);
var getColor = RGBColorsArr[getRandomArrIndex];

So that the next value does not repeat, I decided that it is possible to remove the already received value from the array by index and select randomly from the remaining ones.
BUT! How can this be looped during the N-th function call. So that after deleting all the elements of the array, return to its original version and repeat the procedure.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
I
Ivan Bogachev, 2016-11-12
@sfi0zy

In general, you can generate a random permutation for a set of N elements (12 in your case):

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

And then:
let permutation = getRandomPermutation(colors.length);
let temp = colors.slice();

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

You end up with a randomly sorted array of colors. If you need to start over, you generate the permutation again and the circle closes. Of course, you can not generate the permutation separately, but sort the desired array right away - I divided it here for clarity.
codepen.io/sfi0zy/pen/yVOMmK?editors=0012

O
Oleg, 2016-11-12
@werty1001

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

    }
};

Live example

E
Egor Zhivagin, 2017-02-07
@Krasnodar_etc

A peculiar solution, of course, to make the main blocks even relative without the need) And in the adaptive, change everything pixel by pixel?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question