I like commenter @YuriyGalanter's idea of choosing items randomly until all are taken and only then repeating, so here's an implementation:

function randomNoRepeats(array) {
  var copy = array.slice(0);
  return function() {
    if (copy.length < 1) { copy = array.slice(0); }
    var index = Math.floor(Math.random() * copy.length);
    var item = copy[index];
    copy.splice(index, 1);
    return item;
  };
}

var chooser = randomNoRepeats(['Foo', 'Bar', 'Gah']);
chooser(); // => "Bar"
chooser(); // => "Foo"
chooser(); // => "Gah"
chooser(); // => "Foo" -- only repeats once all items are exhausted.
Answer from maerics on Stack Overflow
Top answer
1 of 15
51

I like commenter @YuriyGalanter's idea of choosing items randomly until all are taken and only then repeating, so here's an implementation:

function randomNoRepeats(array) {
  var copy = array.slice(0);
  return function() {
    if (copy.length < 1) { copy = array.slice(0); }
    var index = Math.floor(Math.random() * copy.length);
    var item = copy[index];
    copy.splice(index, 1);
    return item;
  };
}

var chooser = randomNoRepeats(['Foo', 'Bar', 'Gah']);
chooser(); // => "Bar"
chooser(); // => "Foo"
chooser(); // => "Gah"
chooser(); // => "Foo" -- only repeats once all items are exhausted.
2 of 15
14

Whenever an item is selected, move it to the back of the array and randomly select from a slice of the original array array.slice(0, -5).

var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];

var chooseName = function () {
    num = Math.floor(Math.random() * a.length - 5);
    name = a.splice(num,1);
    a.push(name);
}


window.addEventListener("keypress", function (e) {
    var keycode = e.keyCode;
    if (keycode == 13) {
        chooseName();
    }
}, false);

EDIT: This also has the side-effect of not giving whichever variables happen to tail the list the unfair disadvantage that they won't be considered in the first N calls. If that's a problem for you, maybe try hold a static variable somewhere to keep track of the size of the slice to use and max it out at B (in this case, 5). e.g.

var a = ["Roger", "Russell", "Clyde", "Egbert", "Clare", "Bobbie", "Simon", "Elizabeth", "Ted", "Caroline"];
B = 5; //max size of 'cache'
N = 0;

var chooseName = function () {
    num = Math.floor(Math.random() * a.length - N);
    N = Math.min(N + 1, B);
    name = a.splice(num,1);
    a.push(name);
}
🌐
Reddit
reddit.com › r/learnjavascript › select random elements from array without repeats
r/learnjavascript on Reddit: Select random elements from array without repeats
December 4, 2016 -

Hi! I'm stuck on a problem, and not quite sure how to solve it. I need to randomly select elements from an array, until every element has been selected, but no element can be repeated. Finally, after every element has been selected, it can start over.

I'm able to get it randomly select elements from array, and do the entire thing without repeating by splicing out the selected element, but I'm sure that's not right if I want to start over again once every element has been selected.

Discussions

How to make Math.random not repeat same numbers
Hi! I was trying to make an app and I need to make it show 4 random items from an array but the problem is that with Math.random there’s a possibility to have the same item twice or more times. Does anyone know how to solve this? More on forum.freecodecamp.org
🌐 forum.freecodecamp.org
0
0
August 30, 2020
Random item from array with no repeat using javascript? - Stack Overflow
How to get random items from an array with no repeat? I have an array of elements like var a = ["Mango", "Orange", "Banana", "Apple", "Grapes", "Berry", "Peach"] I want to get 3 random items from More on stackoverflow.com
🌐 stackoverflow.com
May 25, 2018
Random Image with No Repeats - JavaScript - SitePoint Forums | Web Development & Design Community
I’ve got an array of images that I want to randomly attach themselves in some
  • tags. Right now I’ve got everything working great except the images repeat sometimes repeat themselves. Is there any way to make the im…
  • More on sitepoint.com
    🌐 sitepoint.com
    0
    April 29, 2010
    javascript - Random array of numbers without repeating - oojs practice - Code Review Stack Exchange
    Our first community AMA is happening now! Join us live on our YouTube channel. ... Connect and share knowledge within a single location that is structured and easy to search. Learn more about Teams ... function Randoms(c, l, h) { var count = c, min = l, max = h, nums = Array(), self = this; ... More on codereview.stackexchange.com
    🌐 codereview.stackexchange.com
    July 1, 2016
    🌐
    Medium
    medium.com › @will.software.engineer › generate-an-array-of-unique-non-repeating-elements-in-javascript-992b585da29a
    Generate an array of unique, non-repeating elements in Javascript | by Will | Medium
    July 18, 2022 - The second newly created array is an empty array and is assigned the variable newArray. This is the array that we will be inserting the randomly selected, non-repeating elements from arrayCopy into. We use a for loop to tell the Javascript engine to loop through arrayCopy three times.
    🌐
    freeCodeCamp
    forum.freecodecamp.org › javascript
    How to make Math.random not repeat same numbers - JavaScript - The freeCodeCamp Forum
    August 30, 2020 - Hi! I was trying to make an app and I need to make it show 4 random items from an array but the problem is that with Math.random there’s a possibility to have the same item twice or more times. Does anyone know how to s…
    🌐
    GeeksforGeeks
    geeksforgeeks.org › javascript › how-to-create-an-array-containing-non-repeating-elements-in-javascript
    How to create an array containing non-repeating elements in JavaScript ? - GeeksforGeeks
    July 3, 2024 - Remember that a set does not allow duplicate elements. ... // You can take this value from user const n = 5 // Initial empty array const arr = []; // Null Check if (n == 0) { console.log(null) } let randomnumbers = new Set, ans; // We keep adding ...
    🌐
    GitHub
    github.com › SMAKSS › random-array-element
    GitHub - SMAKSS/random-array-element: Selects a random array element without repetition.
    Selecting a random element from an array is simple with Math.random(). However, if you need to ensure that each element is only selected once until all elements have been chosen, @smakss/random-array-element is the ideal solution.
    Author   SMAKSS
    🌐
    Waimin
    waimin.me › generate_unique_randoms
    Generating non-repeating (unique) random numbers in JavaScript | Wai Min's Blog
    The finished implementation of the generating non-repeated randoms should look like this. for (let index = 0; index < TOTAL_CARDS - 1; index++) { let maxIndex = TOTAL_CARDS - 1; let minIndex = index + 1; let swapIndex = Math.floor(Math.random() * (maxIndex - minIndex)) + minIndex; let tmp = col[index]; col[index] = col[swapIndex]; col[swapIndex] = tmp; } We can see from the code above that getting the random index is a bit complicated. We can simplify this if we traverse the array starting from the highest index.
    Find elsewhere
    🌐
    SitePoint
    sitepoint.com › javascript
    Random Image with No Repeats - JavaScript - SitePoint Forums | Web Development & Design Community
    April 29, 2010 - I’ve got an array of images that I want to randomly attach themselves in some tags. Right now I’ve got everything working great except the images repeat sometimes repeat themselves. Is there any way to make the images not repeat? Here’s the code: // Random Image var theImages = new Array() theImages[0] = 'images/newsalerts/courtroom.jpg"' theImages[1] = 'images/newsalerts/officer.jpg"' theImages[2] = 'images/newsalerts/police_dispatcher.jpg"' theImages[3] = 'images/newsalerts/prison...
    🌐
    DEV Community
    dev.to › sagdish › generate-unique-non-repeating-random-numbers-g6g
    Generate unique (non-repeating) random numbers - DEV Community
    November 23, 2020 - Big chances that you'll get at least one repeated number. Solution for this task is to replace each picked (random) number in array with another unused one.
    🌐
    Team Treehouse
    teamtreehouse.com › community › create-random-numbers-with-out-them-repeating-in-javascript
    create random numbers with out them repeating in javascript (Example) | Treehouse Community
    March 24, 2017 - next, setup the while loop where the counter condition is set to check the max length of the numbers array i.e. while (i <= 10) { /* Statements will go here */ } (alternatively max count will be lower, if you don't want to add all 10) inside the loop, declare a new variable to store a temporary random number (it will be destroyed and recreated each time the loop is run) i.e.
    Top answer
    1 of 16
    61

    If I understand right then you're just looking for a permutation (i.e. the numbers randomised with no repeats) of the numbers 1-10? Maybe try generating a randomised list of those numbers, once, at the start, and then just working your way through those?

    This will calculate a random permutation of the numbers in nums:

    var nums = [1,2,3,4,5,6,7,8,9,10],
        ranNums = [],
        i = nums.length,
        j = 0;
    
    while (i--) {
        j = Math.floor(Math.random() * (i+1));
        ranNums.push(nums[j]);
        nums.splice(j,1);
    }
    

    So, for example, if you were looking for random numbers between 1 - 20 that were also even, then you could use:

    nums = [2,4,6,8,10,12,14,16,18,20];
    

    Then just read through ranNums in order to recall the random numbers.

    This runs no risk of it taking increasingly longer to find unused numbers, as you were finding in your approach.

    EDIT: After reading this and running a test on jsperf, it seems like a much better way of doing this is a Fisher–Yates Shuffle:

    function shuffle(array) {
        var i = array.length,
            j = 0,
            temp;
    
        while (i--) {
    
            j = Math.floor(Math.random() * (i+1));
    
            // swap randomly chosen element with current element
            temp = array[i];
            array[i] = array[j];
            array[j] = temp;
    
        }
    
        return array;
    }
    
    var ranNums = shuffle([1,2,3,4,5,6,7,8,9,10]);
    

    Basically, it's more efficient by avoiding the use of 'expensive' array operations.

    BONUS EDIT: Another possibility is using generators (assuming you have support):

    function* shuffle(array) {
    
        var i = array.length;
    
        while (i--) {
            yield array.splice(Math.floor(Math.random() * (i+1)), 1)[0];
        }
    
    }
    

    Then to use:

    var ranNums = shuffle([1,2,3,4,5,6,7,8,9,10]);
    
    ranNums.next().value;    // first random number from array
    ranNums.next().value;    // second random number from array
    ranNums.next().value;    // etc.
    

    where ranNums.next().value will eventually evaluate to undefined once you've run through all the elements in the shuffled array.

    Overall this won't be as efficient as the Fisher–Yates Shuffle because you're still splice-ing an array. But the difference is that you're now doing that work only when you need it rather than doing it all upfront, so depending upon your use case, this might be better.

    2 of 16
    7
    //random number without repetition in JavaScript, Just in one line;
    //it can be used as _id;
    //it not need to store or check;
    

    const myRnId = () => parseInt(Date.now() * Math.random());
    
    console.log(myRnId()); // any random number included timeStamp;

    🌐
    Quora
    quora.com › How-do-I-return-non-repeating-random-numbers-in-JavaScript
    How to return non-repeating random numbers in JavaScript - Quora
    Answer: Well, I don’t know JavaScript, but if you want to avoid repetition (for example, to simulate a lottery drawing), you can do something like this: * Generate a list, array, or similar structure, with the numbers you want to choose from.
    🌐
    Jspsych
    jspsych.org › v7 › reference › jspsych-randomization
    jsPsych.randomization - jsPsych
    Returns an array with the same elements as the input array in a random order, with no repeating neighbors.
    🌐
    Quora
    quora.com › How-do-I-get-an-item-randomly-from-an-array-where-the-item-only-comes-up-once-in-JavaScript
    How to get an item randomly from an array where the item only comes up once in JavaScript - Quora
    When you shuffle an array, the elements will go to random positions, so you can just start indexing it from zero and go up - if you didn't have repeated elements originally, there will be no repeats.
    🌐
    SitePoint
    sitepoint.com › javascript
    Generate Non-Repeating Random Number From A Set - JavaScript - SitePoint Forums | Web Development & Design Community
    February 13, 2018 - I am trying to generate a random number from a set of numbers but it does not seem to be working. Basically what I did was I randomly generated a number from a set and kept track of each generated number so that it won’t be generated again. To try to prevent duplicates from being generated, ...