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

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

ただいまの
回答率

88.83%

javascript の比較関数がわからない

解決済

回答 3

投稿

  • 評価
  • クリップ 3
  • VIEW 5,558

hainan

score 31

理解したいこと

javascriptの比較関数が理解できません。
分かりやすいサイトを探しているのですが、
どなたか教えていただけないでしょうか。

発生している問題・エラーメッセージ

「3ステップでしっかり学ぶ Java Script入門」という本で勉強をしています。
arrayオブジェクトの説明文に、sortメソッドの並び替えを行う構文がありました。

sortメソッドの動きは理解できたのですが、
何故、比較関数(return a - b;)を使うと綺麗にソートできるのか
調べてもわかりませんでした。

<script type="text/javascript">

 function compare(a, b){
  return a - b;
  }

 var ages = new Array(4, 6, 10, 24, 1, 11, 40);
 ages = ages.sort(compare);
 document.write(ages.join(" > "));


</script>

試したこと

以下のサイトを見つけ、コメントの説明を読んでみましたが
理解できませんでした・・・。

(sortメソッドの仕組みはわかりました。)

比較関数の意味がよくわからん。

Sort()メソッドは デフォルトで、a,b,c,dと並んでいる場合、先頭から順にa<=bならa,bのまま、a>bならb,aに、という作業を繰り返していきます。ですから、比較関数で、何によってソートさせたいかを指定することで、いろいろなソートが実現可能になります。b-aとする場合、比較条件がすべて逆になりますから、降順となるわけです。

どなたか、わかりやすいサイトや説明があるサイトをご教授いただけないでしょうか。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+3

こちらの解説にあるとおりで、

compareFunction が与えられた場合、配列の要素は比較関数の返り値に基づきソートされます。もし a と b が比較されようとしている要素の場合、
・compareFunction(a, b) が 0 未満の場合、a を b より小さい添字にソートします。
・compareFunction(a, b) が 0 を返す場合、a と b は互いに関して変えることなく、他のすべての要素に関してソートします。注意: ECMAScript 標準はこの振る舞いを保証しておらず、そのため一部のブラウザ (例えば、遅くとも 2003 年以前のバージョンの Mozilla) はこれを尊重していません。
・compareFunction(a, b) が 0 より大きい場合、b を a より小さい添字にソートします。

つまり、この関数の結果としては、0かプラスかマイナスかだけが考慮されます。実際にreturn a-bを考えてみると、

  • a > bのとき…a - bはプラス、つまりaのほうが後にくるようにソートされる
  • a == bのとき…a - bはゼロ、どちらが先にくるかは(Chromeの場合)わからない
  • a < bのとき…a - bはマイナス、つまりaが先にくるようにソートされる

ということで、文字として出力している不等号とは逆向きのソート順となりそうです。

なお、無関係なところで気になる点がいくつかありました。

  • 配列を作る際はnew Array(1, 2, 3)より[1, 2, 3]のほうが簡潔だしわかりやすい
  • 配列の.sortもとの配列を直接変更するので、結果を代入しないages.sort(compare);だけでいい
  • document.writeはいまどき使うべきでない(テスト用ならconsole.logのほうが便利)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/12 16:52

    何も指定しないときは文字列比較になるので、
    [ 1, 10, 11, 24, 4, 40, 6 ]
    になるのでは

    キャンセル

  • 2017/06/12 16:59

    そうですね、修正します。

    キャンセル

  • 2017/06/12 18:17

    回答ありがとうございました!

    a > bのとき…a - bはプラス、つまりaのほうが後にくるようにソートされる
    a == bのとき…a - bはゼロ、どちらが先にくるかは(Chromeの場合)わからない
    a < bのとき…a - bはマイナス、つまりaが先にくるようにソートされる

    の部分がわからず、今日数時間唸っていました・・・。
    もう一度、本といただいた回答をにらめっこしながら確認していきます。
    ありがとうございます。

    無関係な点についても、ご指摘ありがとうございました。
    本を参考にまだ勉強している最中で、「何がベストなのか」がまだ理解できておりませんでした。
    気になる点がありましたら、(とても勉強になるので)コメントいただけますとありがたいです!
    本当にありがとうございました。

    キャンセル

+2

困ったときのリファレンス

Array.prototype.sort()

compareFunction が与えられた場合、配列の要素は比較関数の返り値に基づきソートされます。もし a と b が比較されようとしている要素の場合、

   compareFunction(a, b) が 0 未満の場合、a を b より小さい添字にソートします。

   compareFunction(a, b) が 0 を返す場合、a と b は互いに関して変えることなく、他のすべての要素に関してソートします。注意: ECMAScript 標準はこの振る舞いを保証しておらず、そのため一部のブラウザ (例えば、遅くとも 2003 年以前のバージョンの Mozilla) はこれを尊重していません。

   compareFunction(a, b) が 0 より大きい場合、b を a より小さい添字にソートします。

というわけで、compareFunction(a, b)a-bとすれば昇順になります。

上記sort()の仕様により、
a<bのとき、compareFunction(a, b)<0となり、「a を b より小さい添字に」して、
a>bのとき、compareFunction(a, b)>0となり、「b を a より小さい添字に」するからです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/12 18:08 編集

    回答ありがとうございます!
    参考になりました!

    キャンセル

+1

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/06/12 18:07 編集

    回答ありがとうございます!
    分かりやすいサイトでした・・・別の内容も併せて勉強させていただきます!

    キャンセル

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

  • ただいまの回答率 88.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る