Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

alvinmrdv's avatar

How can i generate quiz questions with no-repeat.

public function generate(Request $request,$unit_id){

    $unit_id = WordUnit::find($unit_id);
    $words = Vocabulary::where('unit_id',$unit_id->id)->get();
    $vocaquiz = VocaQuiz::insertGetId([
        'student_id' => auth()->user()->id,
        'unit_id' => $unit_id->id,
        'quiz_uniq_code' => uniqid(15)
    ]);

    if($vocaquiz){
        for ($i=0; $i < 50 ; $i++) {
            $selectRandomQues = $words->random();
            $ques = $selectRandomQues->enw.' - ???';
            
            $correctAns = $selectRandomQues->azw;
            $opt1 = $words->where('speech',$selectRandomQues->speech)->random()->azw;
            $opt2 = $words->where('speech',$selectRandomQues->speech)->random()->azw;
            $opt3 = $words->where('speech',$selectRandomQues->speech)->random()->azw;
            $opt4 = $words->where('speech',$selectRandomQues->speech)->random()->azw;
            $arr = collect([$opt1,$opt2,$opt3,$opt4,$correctAns]);

            VocaTest::insert([
                'quiz_id' => $vocaquiz,
                'ques' => $ques,
                'opt1' => $arr[0],
                'opt2' => $arr[1],
                'opt3' => $arr[2],
                'opt4' => $arr[3],
                'opt5' => $arr[4],
                'correct' => $correctAns,
                'created_at' => Carbon::now()
            ]);
        }
    }else{
        toast('Something was wrong','danger');
        return redirect()->back();
    }

    toast('Quiz generated! Check: Ready Quizzes','success');
    return redirect()->back();

}
0 likes
1 reply
rodrigo.pedra's avatar

In summary you need to either keep track of used answers, or remove them from the available pool.

I used the keep track option. Have fun =)

public function generate(Request $request, $unit_id)
{
    $unit_id = WordUnit::find($unit_id);
    $words = Vocabulary::where('unit_id', $unit_id->id)->get();
    $vocaquiz = VocaQuiz::insertGetId([
        'student_id' => auth()->user()->id,
        'unit_id' => $unit_id->id,
        'quiz_uniq_code' => uniqid(15),
    ]);

    if (! $vocaquiz) {
        toast('Something was wrong', 'danger');
        return redirect()->back();
    }

    // this will keep track of all selected answers
    $usedAnswers = [];

    for ($i = 0; $i < 50; $i++) {
        $correctAnswer = $words
            // filters out already selected items
            ->whereNotIn('azw', $usedAnswers)
            ->random();

        $usedAnswers[] = $correctAnswer->azw;

        $question = $correctAnswer->enw . ' - ???';

        $answers = collect();

        foreach (range(1, 4) as $option) {
            $answer = $words
                ->where('speech', $correctAnswer->speech)
                // I assuemed no repeated answers are desired.
                // But if it is a vocabulary quiz, such as looking for synonims
                // replace  `$usedAnswers` with `$answers->all()` so only
                // the answers already used in this questions are avoided
                ->whereNotIn('azw', $usedAnswers)
                ->random()
                ->azw;

            $answers->push($answer);
            $usedAnswers[] = $answer;
        }

        $answers->push($correctAnswer->azw);

        // I added this to randomize
        // the correct option order. before
        // it would be always the fifth option.
        // Remove if unnecessary
        $answers = $answers->shuffle();

        VocaTest::insert([
            'quiz_id' => $vocaquiz,
            'ques' => $question,
            'opt1' => $answers[0],
            'opt2' => $answers[1],
            'opt3' => $answers[2],
            'opt4' => $answers[3],
            'opt5' => $answers[4],
            'correct' => $correctAnswer->azw,
            'created_at' => Carbon::now(),
        ]);
    }

    toast('Quiz generated! Check: Ready Quizzes', 'success');
    return redirect()->back();
}

Please or to participate in this conversation.