質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

4回答

4083閲覧

javaScriptで配列をランダムにするとき、なぜ、sort(()=>{Math.random()-0.5})と記述するのか?

koukit

総合スコア4

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2021/07/19 12:08

編集2021/07/20 00:47

以前、githubの方に公開されている。
javaScriptのクイズゲームのソースコードを見たとき、
下記のような記述があって、何となくやっていることは、分かるんだけど、
なぜ、いちいち下記のようなコードを書くのか意味が分かりません!

例えば、

// 順番をランダムに並べ替えた配列 const arry = ["1+1?","2+2=?","3+3?"]; // この配列をランダムに並び替える。 arry.sort(() => {return Math.random() - 0.5});

このようなコードがあったとして、なぜ、Math.random()の値に、-0.5するのか?また、
このsort()メゾットの中のcallback関数では、どんな処理が行われているのか?
教えてください!

GitHubに公開されてた、クイズゲームのソースコード=>Quiz-App

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2021/07/19 12:11

>githubの方に公開されている。 >javaScriptのクイズゲームのソースコード 出典明示してください。 やってることがわかってるなら(なんとなくでも) 最後の文章見る限りほぼ分かってないように見受けられます。 あと細かいですが「メソッド」ですmethod。
koukit

2021/07/20 01:33

GitHubにある、クイズゲームのソースコードを記載しました。 あと、メゾットじゃなくて、メソッドなんですね。勘違いしていました。 ありがとうございます。
guest

回答4

0

ベストアンサー

公式ドキュメントも見ると、sort()の仕組みについてよく分かるかと思います。
Array.prototype.sort() - JavaScript | MDN

sort()の引数には、比較関数というものが入ります。これは、2つの値a, bを比較して、a < b なら負数を、a > b なら正数を、a == b なら0を返す関数です。

JavaScript

1let array = [4,1,3,5,2]; 2array.sort(function(a, b){ 3 if(a < b){ 4 return -1; 5 } 6 if(a > b){ 7 return 1; 8 } 9 return 0; 10}); 11console.log(array); //出力: [1, 2, 3, 4, 5]

つまり、比較関数が(0または)負数を返したときは、aとbは順序通りなので値の入れ替えは起こらず、逆に比較関数が正数を返したときは、aとbは順序が逆なので、a, bの値が入れ替わります。(実際にはQuickSortが行われているので厳密ではありませんが、とりあえずは比較関数の返り値が正数のときに値が入れ替わると思っておけばよいでしょう。)

そして、Math.random()関数は、0.0以上1.0未満の値をランダムに返します。つまり、Math.random() - 0.5は、-0.5以上0.5未満のランダムな値を返します。

これを比較関数として使うと、比較関数は負数と正数のいずれかをランダムに等確率で返すので、値を「入れ替える」操作と「入れ替えない」操作のいずれかがランダムに起こり、結果として配列がシャッフルされるという訳です。

ただ、本来同じ入力に対しては常に同じ結果を返すべき比較関数がランダムな値を返してしまっているため、この方法は適切とは言えません。他の方法(Fisher–Yates shuffleなど)を使う方がよいでしょう。

投稿2021/07/19 13:22

luuguas

総合スコア501

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

このような方法でランダムな配列を作るのは、適切ではありませんArray#sortの引数にランダム関数を渡した場合、どのような順番に並べ替えられるかは保証されません)。

Fisher-Yates法という、均等にシャッフルできる方法がありますので、それを使いましょう。

投稿2021/07/19 12:26

編集2021/07/19 12:32
maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

anozon

2021/07/20 02:24

あみだくじみたい(適切でないシャッフル)で面白いですね
guest

0

命題の方式がだめなのは実験してみるとわかります
かなり偏った処理になるため使い物になりません

javascript

1const a=Array(10).fill(null).map((_,x)=>x+1); 2a.sort((x,y)=>Math.random()-0.5); 3console.log(a);

なんどか試すと元の配列に親しい配列が返ってくることが見て取れます
こんな風にすると比較的単純なロジックでソート可能です

javascript

1const a=Array(10).fill(null).map((_,x)=>x+1); 2a.unshift(...a.map(x=>[x,Math.random()]).sort((x,y)=>x[1]-y[1]).map(x=>x[0])); 3a.splice(a.length/2); 4console.log(a);

投稿2021/07/20 01:40

yambejp

総合スコア116724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2021/07/20 23:38 編集

> こんな風にすると比較的単純なロジックでソート可能です ソートなので、O(n log n)になる点は要注意かもしれないです(Fisher-YatesはO(n)での実装が可能です)。
guest

0

なぜ、Math.random()の値に、-0.5するのか?

0以上1未満の乱数から0.5を引けば、正負の割合がほぼ半々になるからでしょう。

これが分からないと言うことは、sort関数の仕様を調べていないのでは?
調べてから質問しましょう。

また、このsort()メゾットの中のcallback関数では、どんな処理が行われているのか?

メソッドのことをメゾットと書く人がたまにいるようですが、どういうコミュティーでの慣習なのでしょうか?

コールバック関数では、要素の大小によって、正または負またはゼロを返すことになっているので、
このコードを書いた人は、ランダムに正負の数を返す関数を使えば、ランダムに並べ替えられると思ったのでしょうが、同じ要素に対しては同じ結果を返す必要があるので、これでは駄目です。
(この関数だと、同じ要素を引数に呼び出しても、呼び出すごとに違う結果になり得るので駄目)

投稿2021/07/19 14:28

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問