Consecutively return a random item from a JavaScript array

hybrid_alex profile image Alex Carpenter ・1 min read

View this post on alexcarpenter.me

The other week I was working on a side project where I needed to consecutively return a random item from an array via a button click.

To do this, I first created a function that returns a random item from an array.

function randomItem(arr) {
  return arr[Math.floor(Math.random() * arr.length)];

The problem with using only the randomItem function here, is that it was not uncommon to return the same item twice in a row.

To fix that issue, I made use of a do...while loop to call the randomItem function until it returned a result which is not equal to the previously selected item.

So while prevItem is equal to currentItem, run the randomItem function.

var fruit = ['Apples', 'Oranges', 'Pears'];

var currentItem = randomItem(fruit);

btn.addEventListener('click', function () {
  var prevItem = currentItem;
  do {
    currentItem = randomItem(fruit);
  } while (prevItem === currentItem);
}, false);

Now when we click the button, we will never get the same item returned consecutively.

Checkout the demo and open the console to see it in action.


Editor guide
eostrom profile image
Erik Ostrom

Another way to do it is to create an array that contains every item except the current one, and then take a random item from that:

btn.addEventListener('click', function() {
  var otherFruits = fruit.filter(function(item) { return item !== currentItem });
  currentItem = randomItem(otherFruits);
}, false);
hybrid_alex profile image
Alex Carpenter Author

Definitely, but it seemed more performant to not create a new array using filter on every click.

eostrom profile image
Erik Ostrom

It's hard to know, right? I would guess the average performance for my version is worse, for the reason you mentioned. But the worst-case performance for your version is worse, because in theory that loop can spin and spin until the random number generator picks a different fruit.

But really, the performance costs we're talking about aren't important, if they only happen once per human click interval. I'd favor readability... if I could just decide which one was more readable.

Thread Thread
eostrom profile image
Erik Ostrom

... Anyway, I just think it's fun to see multiple ways to do things.