JavaScript の sort メソッドについて
- 評価
- クリップ 3
- VIEW 5,176

退会済みユーザー
現在、JavaScript本格入門という書籍を読みながら勉強しています。
sort
メソッドについて教えてください。
書籍には sort
メソッドの説明している箇所に下記のコードがあります。
var ary = [5, 25, 10];
// ① 結果:[10, 25, 5](文字列としてソート)
console.log(ary.sort());
// ② 結果:[5, 10, 25](数値としてソート)
console.log(ary.sort(function(x, y) {
return x - y;
}));
書籍には下記のように説明があります。
sortメソッドは、デフォルトで配列を文字列として辞書順にソートします。このルールを変更するには、引数として、以下のような関数を定義します。
・引数は2つ(比較する配列要素)
・第1引数が第2引数より小さい場合は負数、大きい場合は正数を返す
①に関しては引数を省略しているので、1から順番に並び替えが行われたのかと思います。
②の記述について理解できません。
記述例は、sort
メソッドの第一引数に無名関数を記述して、無名関数の仮引数に x
と y
と記述しているかと思います。
第1引数が第2引数より小さい場合は負数、大きい場合は正数を返す
上記の説明の箇所があてはまるのかと思いますが、どのような意味かわかりません。
仮引数に入る x
と y
の値を比較しているのでしょうか?
x
と y
にはどの値がどのような順番で入るのでしょうか?
負数、正数を返すとありますが、これもわかりません。
仮に 5
と 25
の値を比較した場合でも、負数はどこにもないかと思います。
負数、正数を返すとはどのような意味なのでしょうか?
もう一つありまして、関数内で記述している return x - y
についてもどのような意味なのかわかりません。
戻り値を返しているということはわかりますが、x - y
とするだけでなぜ数値としてソートされるのでしょうか?
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+5
そこまでわかっているのなら自力で解決できるとおもいますよ。
試しにconsole.logを以下のように埋め込んでみて観測してみたらどうでしょうか?
var ary = [5, 25, 10];
// ② 結果:[5, 10, 25](数値としてソート)
console.log(ary.sort(function(x, y) {
console.log(`x= ${x}, y=${y} result = ${x-y}`);
return x - y;
}));
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+2
どのようなソートアルゴリズムを使っているかは、ブラウザによりますが仮に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が提供されています。ですので正直ソートアルゴリズムが何かを気にしなくても何の問題もなく使えます。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
参考情報
意外と簡単にできる、JavaScriptでオブジェクトの配列を並べ替える方法
https://www.webprofessional.jp/sort-an-array-of-objects-in-javascript/Array.prototype.sort()
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.10%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2017/09/25 19:10 編集
```javascript
var ary = [25, 15, 5];
console.log(ary.sort(function(x, y) {
console.log(ary);
console.log(`x= ${x}, y=${y} result = ${x-y}`);
return x - y;
}));
```
console.log(ary) を追加してみて、Chromeのデベロッパーツールで確認すると下記のようになりました。
```javascript
(3) [25, 15, 5]
x= 25, y=15 result = 10
(3) [15, 25, 5]
x= 25, y=5 result = 20
(3) [15, 25, 25]
x= 15, y=5 result = 10
(3) [5, 15, 25]
```
2つの値を比較して正負によって要素を移動しているのかと思います。
並び替えをしているのはわかりますが、途中で [15, 25, 25] になるのはなぜでしょうか?
5 という要素はどこにいったのでしょうか?
あと、2つの値を比較して並び替えをしているので、これがバブルソートという手法ですか?