Array.prototype.sort()が数値を文字列として並べ替える理由
比較関数を渡さないsort()は、number[]という型が付いていても要素を文字列に変換してUnicodeコードポイント順に並べ替えます。数値の大小とは無関係な結果になります。
なぜエラーが出ないのか
出力: [ 10, 25, 40, 5 ]
(エラーなし)- TypeScriptは何も報告しません。型検査も構文も正しいためです
出力: [ 10, 25, 40, 5 ]- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるか、コードを目で追うしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 const nums: number[] = [10, 5, 40, 25]; 2 nums.sort( ); ^ 3 console.log(nums);
出力: [ 10, 25, 40, 5 ]
比較関数を渡さないsort()は要素を文字列として比較します。"10"は"5"より辞書順で小さいため、数値としては逆転した順序になります。
直し方: (空) を (a, b) => a - b にします。
広告
広告スロット(未設定)
パターン2
1 const scores: number[] = [9, 80, 700, 6]; 2 scores.sort( ); ^ 3 console.log(scores);
出力: [ 6, 700, 80, 9 ]
既定のsort()は文字列比較のため、"700"は"80"より前に来ます。数値順にしたい場合は比較関数が必須です。
直し方: (空) を (a, b) => a - b にします。
パターン3
1 const ids: number[] = [100, 21, 3]; 2 ids.sort( ); ^ 3 console.log(ids);
出力: [ 100, 21, 3 ]
"100"、"21"、"3"を文字列として比較すると先頭の文字("1" < "2" < "3")で決まるため、この順のまま並びます。
直し方: (空) を (a, b) => a - b にします。
よくある誤解
「number[]型なのだから、sort()は数の大小で並べ替えてくれるはず」という考えは誤りです。sort()の既定の比較は要素の型を問わず文字列化して行われるため、型を付けても挙動は変わりません。
まとめ
Array.prototype.sort()が数値を文字列として並べ替える理由は初級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。