はじめに
JavaScriptで配列をソートする処理を書いていて数値が期待通りに並ばない問題があったので、調べて分かった点を整理します。
デフォルトソートの挙動
Array.prototype.sort は、比較関数を渡さない場合に要素を文字列として比較するらしいです。このため、数値配列をソートすると辞書順になってしまいます。ややこし...
[10, 2, 5].sort();
// ["10", "2", "5"] 文字列として扱われる
数値を正しくソートする方法
比較関数を指定する必要があります。引数 a と b の差を返すことで、昇順・降順の制御ができます。
[10, 2, 5].sort((a, b) => a - b);
// [2, 5, 10]
[10, 2, 5].sort((a, b) => b - a);
// [10, 5, 2]
文字列のソート
文字列をソートした際、大文字・小文字や日本語の扱いが直感と異なる結果になることがありました。その場合は localeCompare を利用すると自然な並びになります。
['Banana', 'apple', 'Orange'].sort();
// ["Banana", "Orange", "apple"]
['Banana', 'apple', 'Orange'].sort((a, b) => a.localeCompare(b));
// ["apple", "Banana", "Orange"]
['あ', 'い', 'ア', 'イ'].sort((a, b) => a.localeCompare(b, 'ja'));
// ["あ", "ア", "い", "イ"]
安定ソートの仕様
ES2019以降の仕様では Array.prototype.sort が安定ソートとなっています。
ただ古い環境では不安定なケースがあるため注意が必要。