assuming you have your questions in an array, you can use the shuffled method to get a new array with the contents shuffled, or a shuffle method to shuffle it in place (remember to make it a var instead of let if you want to shuffle in place).
let allQuestions = [
Question(text: "Life, the Universe and Everything", answers: [
Answer(text: "42", correct: true),
Answer(text: "What?", correct: false),
]),
Question(text: "Monoid in the category of endofunctors", answers: [
Answer(text: "Tuple", correct: false),
Answer(text: "Monad", correct: true),
]),
]
let questionsInRandomOrder = allQuestions.shuffled()
Assuming you have some huge array with all of your questions, and you want to get a small number of random elements without duplicates, I would do something like this:
let questionDatabase: [Question] = ...
let questionsPerQuiz = 10
// Select some random indexes, without duplicates.
var selectedQuestionIndexes: Set<Int> = []
while selectedQuestionIndexes.count < questionsPerQuiz {
selectedQuestionIndexes.insert(questionDatabase.indices.randomElement())
}
// Get the question from each selected index.
// Shuffle again because they are returned in hash-table order.
var quiz: [Question] = selectedQuestionIndexes.lazy.map { idx in
questionDatabase[idx]
}.shuffled()
This allows you to avoid copying and shuffling the entire database when you only want a few items.
That being said, pure randomness might not actually make the most fun quiz; good question selection can make a big difference. There's often some level of structure behind it - like maybe having separate easy/medium/hard question pools, and mixing them a little (so maybe there's a 5% chance of a hard question in medium mode), or having separate categories so you can control how often particular topics appear (randomness could give you 10 geography questions in a row). So try things out!
I have about 400 questions, so as not to make it boring and lengthy, I would love it if only 20, 50 or 100 random questions are shown in random order. How can I do this?