0

So I have this Math.random function and it occasionally returns the same object twice in a row or more when I call the function. Any ideas how to fix this?

let currentQuote;

let quoteGenerator = (response) => {
    let newQuote = response[Math.floor(Math.random() * response.length)];
    while (newQuote === currentQuote) {
        newQuote = response[Math.floor(Math.random() * response.length)];
        currentQuote = newQuote;
        console.log(newQuote);
        return newQuote;
    }
};
Tim Lewis
  • 27,813
  • 13
  • 73
  • 102
preston17
  • 19
  • 5
  • keep track of the previous value and request a new random number if it didn't change – Diego D Feb 23 '23 at 14:46
  • Store the previous quote and if the newQuote is the same, generate another. FWIW, true randomness will have some duplication. – mykaf Feb 23 '23 at 14:46
  • 1
    Consider constructing a permutation of the possible values, and returning the elements of the permutation one by one. That will guarantee that each element is returned exactly once. After you run out of elements, generate another permutation and repeat the process. – Robert Dodier Feb 23 '23 at 17:03
  • @RobertDodier would you be able to show me an example? I'd really appreciate it – preston17 Feb 23 '23 at 20:12
  • 1
    See [Birthday Problem](https://en.wikipedia.org/wiki/Birthday_problem) for why this happens, [Fisher Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle) for how to fix it. [RosettaCode.org](https://rosettacode.org/wiki/Knuth_shuffle#JavaScript) has a shuffle implementation in javascript. – pjs Feb 23 '23 at 21:02
  • Do not add (RESOLVED) to the title. If you'd like to add your own resolution, post a self-answer or accept the answer below. – Tim Lewis Mar 30 '23 at 20:05

1 Answers1

0

The problem is that your code only ever rerolls the random value once, since the while ends with a return. If you get the same value thrice in a row, it will get returned anyway. You'll need to move the assignment and return out of the loop.

let lastQuote = null;

let quoteGenerator = (response) => {
    let newQuote = response[Math.floor(Math.random() * response.length)];

    while (newQuote === lastQuote) {
        newQuote = response[Math.floor(Math.random() * response.length)];
    }

    lastQuote = newQuote;
    return newQuote;
};
  • I'm implemented this into my code but still will get a duplicate here and there? Is there a way to avoid it or is it just inevitable that it will repeat? – preston17 Feb 23 '23 at 19:50