@zzz12 (zzz 12)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

配列の要素をランダムに表示したいのです。

はじめて質問させていただきます。

ulの li に配列の要素を割り当てて、reloadした際にランダムに表示させるようにしたいのです。

text.
・1
・2
・3

が

・3
・1
・2

のように。

自分で書いたコードがこちらになります。

qiita.js
// 配列
let numbers = ["1","2","3"];

var html = '';

// ランダム
const  randomNum = (numbers[Math.floor(Math.random() * numbers.length)]);

numbers. forEach  (function( number ) {
     html += '<li>'+randomNum+'</li>';

});


document.querySelector('ul').innerHTML = html;

しかしこれだと結果が

・1
・1
・1

のようになってしまいます。

どうしたら良いでしょうか?

超初心者なので、コードや内容が酷いと思いますが教えて頂けると助かります。
よろしくお願いします。

*投稿の仕方が間違っていたらすいません。

1 likes

2Answer

質問者さんのコードでは

const randomNum = (numbers[Math.floor(Math.random() * numbers.length)]);

の部分において一度しか`randomNum`が更新されていないため、その後の`forEach`のループでも常に同じ値しか使えません。

---

配列の要素をランダムに並び替えるという意図でよろしいでしょうか?
それでしたら以下のようなコードが書けます。

```js
let numbers = ["1","2","3"];
let shuffled = numbers.concat(); // コピー
let html = "";

// 配列全体(`0` から `shuffled.length - 1`)から、
// 終端を順番に先頭側にずらして、狭めていくイメージ
for(let i = shuffled.length - 1; i > 0; i--){
	const randomIndex = Math.floor(Math.random() * (i + 1));

	// ここから 終端の要素と、ランダムに選んだ要素を入れ替える処理
	const tmp = shuffled[i];
	shuffled[i] = shuffled[randomIndex];
	shuffled[randomIndex] = tmp;	
}

shuffled.forEach(function( number ) {
     html += '<li>' + number + '</li>';
});

document.querySelector('ul').innerHTML = html;

ランダム入れ替えの処理は Fisher-Yates Shuffle で調べてみてください。


(余談ですが、次のような書き方もできます(おまけ))

let numbers = ["1","2","3"];
let shuffled = numbers.concat();

for(let i = shuffled.length - 1; i > 0; i--){
	const randomIndex = Math.floor(Math.random() * (i + 1));

	// 分割代入(Destructuring assignment)を利用
	[shuffled[i], shuffled[randomIndex]] = [shuffled[randomIndex], shuffled[i]];
}

// `Array#map`、アロー関数(Arrow Function)、テンプレートリテラル、`Array#join`を利用
let html = shuffled.map(number => `<li>${number}</li>`).join("");

document.querySelector('ul').innerHTML = html;
1Like

Comments

  1. @zzz12

    Questioner

    @lemon2003様
    遅れてすいません。
    ご回答ありがとうございました。

    書いて頂いたコードをコピペして希望通りの結果が得られました。
    ありがとうございました。助かりました。

    あれからコードを理解しようしたのですが
    こちらがどうしても理解できなかったです。


    ```

    // ここから 終端の要素と、ランダムに選んだ要素を入れ替える処理
    const tmp = shuffled[i];
    shuffled[i] = shuffled[randomIndex];
    shuffled[randomIndex] = tmp;

    ```
    それでも解決できよかったです。
    ありがとうございました。


(コメント欄では不都合なのでこちらで)


// ここから 終端の要素と、ランダムに選んだ要素を入れ替える処理
const tmp = shuffled[i]; // 1.
shuffled[i] = shuffled[randomIndex]; // 2.
shuffled[randomIndex] = tmp; // 3.

ここでしていることを分解すると

  1. tmpshuffled[i]を避けておく
  2. shuffled[i]shuffled[randomIndex]を代入(shuffled[i]は避けてあるから上書きしてもOK)
  3. shuffled[randomIndex]tmp(=もとのshuffled[i])を代入

shuffle.png

1Like

Comments

  1. @zzz12

    Questioner

    @lemon2003様 

    非常にわかりやすく丁寧な説明に大変感謝しております。
    理解できました。自分が何に混乱してたのかもわかりました。
    そしてコメントと投稿の違いも理解できました。
    本当にありがとうございました。

Your answer might help someone💌