【JavaScript】配列の要素をランダムに表示する

## はじめに
[こちらの記事](https://qiita.com/Yuzaburo/items/d5fb2ed8ef0f9769df07)で紹介した野球クイズアプリ開発の続編です。

現状だと問題が順番に表示されているのですが、これをランダムに表示されるようにしたいと思います。

## 修正したい点
* 問題を順番ではなく、ランダムに表示したい

```javascript: quizController.js
import quizData  from "../data/quizdata.js";

let currentQuestionIndex = 0;
let score = 0;

function displayQuestion() {
    const question = document.getElementById('question');
    const scoreDisplay = document.getElementById('score');
    
    // 現在の質問と選択肢を表示
    question.textContent = quizData[currentQuestionIndex].question;
    quizData[currentQuestionIndex].choices.forEach((choice, index) => {
        const button = document.getElementById(`btn${index}`);
        button.textContent = choice;
        button.onclick = () => checkAnswer(choice);
    });
    
    // スコアを更新
    scoreDisplay.textContent = `スコア: ${score}`;
}

function checkAnswer(choice) {
    if (choice === quizData[currentQuestionIndex].answer) {
        score++;
        alert('正解！');
    } else {
        alert('不正解！');
    }

    currentQuestionIndex++;
    if (currentQuestionIndex < quizData.length) {
        displayQuestion();
    } else {
        alert(`クイズ終了！あなたのスコアは ${score} 点です。`);
        resetQuiz();
    }
}

// もしクイズが終了したら、最初の質問を表示する
function resetQuiz() {
    currentQuestionIndex = 0;
    score = 0;
    shuffle(quizData);
    displayQuestion();
}

// クイズの初期表示
displayQuestion();
```

```javascript: quizdata.js
const quizData = [
    {
      question: "日本はWBCで何回優勝している？",
      choices: ["1回", "2回", "3回", "4回"],
      answer: "3回"
    },

    {
      question: "日本のプロ野球は何球団ある？",
      choices: ["10球団", "11球団", "12球団", "13球団"],
      answer: "12球団"
    },

    {
      question: "日本のプロ野球は何リーグある？",
      choices: ["1リーグ", "2リーグ", "3リーグ", "4リーグ"],
      answer: "2リーグ"
    },

    {
      question: "野球の試合で、チームが攻撃側から守備側に交代するのは、何アウト後？",
      choices: ["1アウト", "2アウト", "3アウト", "4アウト"],
      answer: "3アウト"
    },

   // 以下略
];

export default quizData;
```

## 解決方法
* 問題の出題順をランダム化するためには、quizData配列をシャッフルする
* 具体的には「Fisher-Yatesアルゴリズム」を使う

```javascript
// 
function shuffle(array) {
    for(let i = (quizData.length - 1); i > 0; i--) {
        const j = Math.floor(Math.random() * (i - 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}

// クイズ開始時に選択肢をシャッフル
shuffle(quizData);
        
```

Fisher-Yatesアルゴリズムに関する説明は以下の記事などが参考になります。

https://qiita.com/shoheiyokoyama/items/4a49674f1e65671ea52b

一言で言うと、shuffle関数では配列からランダムに要素を抽出して入れ替えています。

そのためにはランダムな0〜1未満の数字を生成するMath.random()と、小数点以下の数字を切り捨てるMath.floor()を使います。

## 完成形

```javascript: quizController.js
import quizData  from "../data/quizdata.js";

let currentQuestionIndex = 0;
let score = 0;

function shuffle(array) {
    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]];
    }
}

// 中略・・・

// クイズ開始時に選択肢をシャッフル
shuffle(quizData);

function resetQuiz() {
    currentQuestionIndex = 0;
    score = 0;
    shuffle(quizData); // クイズをリセットする際にも選択肢をシャッフル
    displayQuestion();
}

// クイズの初期表示
displayQuestion();
```

これで問題がランダムな順番で表示されるようになりました！


## 参考
https://qiita.com/shoheiyokoyama/items/4a49674f1e65671ea52b

https://zenn.dev/k_kazukiiiiii/articles/cf3256ef6cbd84

## 最後に
今後はそれぞれの問題に難易度を設定して配点の比重を変えたり、クイズの解説を表示できるようにしてみたいと思います！

コメントやアドバイスがあればお待ちしています！！

お読みいただきありがとうございました。