Next.js Discord

Discord Forum

How to add randomness to .map() function

Answered
Rhinelander posted this in #help-forum
Open in Discord
RhinelanderOP
I want this code to randomly map trough those answers. As in db right answer is always first and I need to add randomness to this to make quiz.
    question.answers.map((answer) => (
            <AnswerOption
              key={answer.id}
              answer={answer}
              selectedAnswer={selectedAnswer}
              handleAnswerClick={handleAnswerClick}
            />
          ))
Answered by African Slender-snouted Crocodile
use a set seed for the randomness function? This way it's determenistic. Something from these maybe: https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript
View full answer

24 Replies

RhinelanderOP
I don't want to use client component for this. But my solution is this code
function shuffleArray(array: Answer[]) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}
const shuffledAnswers = shuffleArray([...question.answers]);
And after map trough it
But if I do that
When i refresh it reshuffles it so when i navigate to next question i first get 1 order then another diffrent order
It is just bad
But i also don't want to manipulate that in db as every time i go over that quiz i want answers to be in diffrent order
you can use a simpler way for that:
[1,2,3,4,5,6].sort(() => 0.5 - Math.random() );

That's of course not the best and efficient way, but isn't that complex like your example.
RhinelanderOP
yeah but it still the issue where it renders diffrent on every refresh
I want to stay the same
on refresh
Thrianta
Perhaps you could cache it with unstable_cache from next/cache
Thrianta
Export const getQuestionAndShuffledAnswers = unstable_cache(async (questionId) => {
Const questionAndAnswers = await getQuestionAndAnswers(questiodId)

Const shuffledAnswers = questionAndAnswers.answers.sort(…)


Return {
…questionAndAnswers,
answers: shuffledAnswers
}
})
This will call the db once (first time a user calls this) then it will serve the cached result to every user after that, including on page refreshes.
This function must be called on the server only.
To reshuffle the answers you would have to invalidate the cache. If this is functionality you need let me know and I’ll type up a more complete example
African Slender-snouted Crocodile
use a set seed for the randomness function? This way it's determenistic. Something from these maybe: https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript
Answer
African Slender-snouted Crocodile
if I understood right what the issue is lol
@Rhinelander yeah but it still the issue where it renders diffrent on every refresh
use a pseudo-random number generation algorithm with seeding, see here for example: https://stackoverflow.com/q/521295

with the same seed, the algorithm always returns the same number, making it stable across refreshes.

but slight changes in the seed cause the value to vary wildly without pattern, hence it's "random".

making a seed of userId + a server side secret is good enough i think
unstable_cache is also a solution but first it is unstable and second this problem doesn't really need nextjs-specific features
African Slender-snouted Crocodile
oh ye just said that nice
oh wait yeah you also mentioned that, didn't know before i sent the message. yep, that's the best solution to this problem
RhinelanderOP
Thank you! I will try to implement that as you said.