質問: [5, 25, 10]; // 1 結果:[10, 25, 5](文字列としてソート) console.log(ary.sort()); // 2 結果:[5, 10, 25](数値としてソート) console.log(ary.sort(function(x, y) { return x - y; })); ``` 書籍には下記のように説明があります。 > > sortメソッドは、デフォルトで配列を文字列として辞書順にソートします。このルールを変更するには、引数として、以下のような関数を定義します。 > > > ・引数は2つ(比較する配列要素) > > ・第1引数が第2引数より小さい場合は負数、大きい場合は正数を返す > > > 1に関しては引数を省略しているので、1から順番に並び替えが行われたのかと思います。 2の記述について理解できません。 記述例は、`sort`メソッドの第一引数に無名関数を記述して、無名関数の仮引数に `x` と `y` と記述しているかと思います。 > > 第1引数が第2引数より小さい場合は負数、大きい場合は正数を返す > > > 上記の説明の箇所があてはまるのかと思いますが、どのような意味かわかりません。 仮引数に入る `x` と `y` の値を比較しているのでしょうか? `x` と `y` にはどの値がどのような順番で入るのでしょうか? 負数、正数を返すとありますが、これもわかりません。 仮に `5` と `25` の値を比較した場合でも、負数はどこにもないかと思います。 負数、正数を返すとはどのような意味なのでしょうか? もう一つありまして、関数内で記述している `return x - y` についてもどのような意味なのかわかりません。 戻り値を返しているということはわかりますが、`x - y` とするだけでなぜ数値としてソートされるのでしょうか?
回答: どのようなソートアルゴリズムを使っているかは、ブラウザによりますが仮にchromeだとしたら ソートの該当コードは以下となります。 https://github.com/v8/v8/blob/master/src/js/array.js#L766 ``` function QuickSort(a, from, to) { var third_index = 0; while (true) { // Insertion sort is faster for short arrays. if (to - from <= 10) { InsertionSort(a, from, to); return; } if (to - from > 1000) { third_index = GetThirdIndex(a, from, to); } else { third_index = from + ((to - from) >> 1); } // Find a pivot as the median of first, last and middle element. var v0 = a[from]; var v1 = a[to - 1]; var v2 = a[third_index]; var c01 = comparefn(v0, v1); if (c01 > 0) { // v1 < v0, so swap them. var tmp = v0; v0 = v1; v1 = tmp; } // v0 <= v1. var c02 = comparefn(v0, v2); if (c02 >= 0) { // v2 <= v0 <= v1. var tmp = v0; v0 = v2; ``` ただこのコードを見てもらうとわかりますがconsole.logを埋め込んだ関数は上記コードの場合 `comparefn`になります。 `comparefn`の中でarrayの内容をログ出力すると、ソート処理の途中でログ出力することになるため `[15, 25, 25]`のような中途半端な出力になるわけです。 ちなみに要素数が10以下だと挿入ソート。10より大きければクイックソートを使っているみたいですね。 (chrome、V8エンジンの場合) 大抵の言語では、2つの要素を比較する関数を用意すると 上手くソートしてくれるAPIが提供されています。ですので正直ソートアルゴリズムが何かを気にしなくても何の問題もなく使えます。