4

At the moment, I have some code to pick one random object from an array and it works well. However, I don't want any repeats in the output. I want to randomly provide a new site link on the click of a button, and it should be different every time (until of course we run out of objects in the array). What code can I add to this to prevent any repetition?

Here's the sample code:

<script>
  var links = [
    "page-1",
    "page-2",
    "page-3",
    // ...
    "page-108",
  ]

  function openSite() {
    var randIdx = Math.random() * links.length;
    randIdx = parseInt(randIdx, 10);
    var link = 'https://websitename.com/page/' + links[randIdx];
    window.location.assign(link);

  };
</script>
hgb123
  • 13,869
  • 3
  • 20
  • 38
Meghan K
  • 51
  • 3
  • 1
    Store the generated index and check against it every time a new random number is generated. When out of the item, you can reset or anything you like. – Ashish Yadav Aug 19 '20 at 12:29
  • 1
    Is removing the element out of the array an option? This would mean the array need to be refilled when you ran out of items. – Mark Baijens Aug 19 '20 at 12:31
  • 1
    Does this answer your question? [How to randomize (shuffle) a JavaScript array?](https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array) – ASDFGerte Aug 19 '20 at 12:32
  • Hum ! You need something that holds the indexes that have been already visited. – Sinan Aug 19 '20 at 13:03
  • If you refer to different HTTP requests, then you need to store used values somewhere (a database, LocalStorage, whatever). – Álvaro González Aug 19 '20 at 13:55

5 Answers5

2

There are different ways of solving this problem.

One would be to make a "shuffled" copy of your array, and then, instead of picking a random item from the original array, you pick an item from the shuffled array in sequence. There are also different algorithms for shuffling an array. You can find some here: How to randomize (shuffle) a JavaScript array?.

Another option would be to make a copy of your array, and every time you pick an item, you remove it from the copy array, and then you use the copy array length to find the index of the next random item.

Thiago Barcala
  • 6,463
  • 2
  • 20
  • 23
1

An option is to

  1. shuffle the array, see here for a good shuffling algorithm
  2. repeatedly use links.pop() to remove and return the last item until its empty

eg

links = shuffle(links)
for (let i=0, L=links.length; i<L; i++) {
    let random_item = links.pop()
}
dwb
  • 2,136
  • 13
  • 27
1

Please consider explanation from comments. Array.prototype.splice()

var links = ["page-1", "page-2", "page-3", "page-108"];
// array to hold used link values which are removed form links.
// when links is empty then assign all values back from linksUsed and clear linksUsed.
var linksUsed = [];

function openSite() {
  // if links is empty then assign all values back from linksUsed and clear linksUsed.
  if (links.length == 0) {
    links = linksUsed;
    linksUsed = [];
  }

  var randIdx = Math.random() * links.length;
  randIdx = parseInt(randIdx, 10);
  // splice will remove n items starting from index.
  // First parameter value is starting index and 2nd parameter is delete count
  var link = links.splice(randIdx, 1)[0];
  // push removed link to linksUsed
  linksUsed.push(link);

  // update link
  link = 'https://websitename.com/page/' + link;
  // for testing commented below line and added log
  // window.location.assign(link);
  console.log(link);
};


//for (let i = 0; i < 5; i++) {
//  openSite();
//}
<button onclick='openSite()'>Open Site</button>
Karan
  • 12,059
  • 3
  • 24
  • 40
  • This code is working well in terms of preventing any repeats, but it's randomizing every few seconds. I want it to randomize on the click of a button. The button is programmed to do this, but with this Java code, that's not working. Any suggestions how I can make that work? – Meghan K Aug 20 '20 at 13:54
  • I guess what you need is call `openSite` function from button's `onclick` like ` – Karan Aug 21 '20 at 04:49
  • That's exactly why my HTML says but it's not working properly. Anything else that could assist that? – Meghan K Aug 21 '20 at 06:53
0
<script>
var links = ["page-1",
             "page-2",
             "page-3",
                ...
             "page-108",
              ]

         currentPage=1;

        function openSite() {
                var randIdx = Math.random() * links.length;
                randIdx = parseInt(randIdx, 10);
                console.log(currentPage)
               
               //this condition will detect repeat then increase randIdx by 1
                 if(randIdx==currentPage){
                   console.log('REPEATED')
                   randIdx++
                }
                // console.log(randIdx )
                   var link = 'https://websitename.com/page/' + links[randIdx];
                   window.location.assign(link);
                 
            currentPage=randIdx;

               
     };

</script>
<button onclick='openSite()'>CLICK</button>

This Simple condition will solve your repeating problem

0

You can do this with Rando.js' randoSequence shuffle function and JavaSript's pop function like this:

var links = ["page-1", "page-2", "page-3", "page-4"], shuffledLinks = [];

function getRandomLink() {
  return 'https://websitename.com/page/' + (shuffledLinks = shuffledLinks.length ? shuffledLinks : randoSequence(links)).pop().value;
}

for(var i = 0; i < 10; i++) console.log(getRandomLink());
<script src="https://randojs.com/2.0.0.js"></script>

This will create an array of shuffled links, remove from the shuffled array one at a time, and refill it as needed.

Aaron Plocharczyk
  • 2,776
  • 2
  • 7
  • 15