【デザイン基礎|実務向け】JavaScriptのArray.prototype.sort()を正しく使いこなすための実務ガイド

Web開発において、データの一覧をソートする場面は非常に多くあります。しかし、JavaScriptのArray.prototype.sort()は「デフォルトの挙動」が直感的でないため、初心者から中級者までが思わぬバグに遭遇しやすいメソッドでもあります。本記事では、実務で安全かつ正確にデータを扱うためのソートの仕組みと注意点を解説します。

基礎知識:なぜ数値のソートで失敗するのか?

JavaScriptのsort()メソッドは、デフォルトでは「要素を一度文字列に変換し、UTF-16コード単位の順序で比較」します。
これが原因で、数値の「10」と「2」を比較した際に、「1」と「2」が比較され、「10」の方が「2」よりも先に来るという現象が発生します。実務では、数値やオブジェクトの配列を扱うことがほとんどですので、必ず「比較関数(compareFn)」を記述する必要があります。

実装:比較関数の作り方

比較関数は、2つの引数(a, b)を取り、以下のルールに従って数値を返します。
・負の値を返す:a を b の前に配置
・正の値を返す:b を a の前に配置
・0を返す:順序を変更しない

サンプルプログラム

以下は、実務で頻出する「数値の昇順ソート」と「オブジェクト配列のプロパティ値によるソート」のコード例です。

// 1. 数値の昇順ソート
const numbers = [10, 2, 8, 1, 15];
// 引数a, bの差分をとることで昇順に並べ替えが可能
numbers.sort((a, b) => a – b);
console.log(numbers); // [1, 2, 8, 10, 15]

// 2. オブジェクトの配列を特定のプロパティでソート
const users = [
{ name: ‘Alice’, age: 30 },
{ name: ‘Bob’, age: 25 },
{ name: ‘Charlie’, age: 35 }
];

// 年齢(age)で昇順にソートする
users.sort((a, b) => a.age – b.age);
console.log(users);

// 3. 文字列を正しくソートする(日本語など)
const items = [‘バナナ’, ‘アーモンド’, ‘チェリー’];
// localeCompareを使うと辞書順で正しくソートされる
items.sort((a, b) => a.localeCompare(b, ‘ja’));
console.log(items); // [‘アーモンド’, ‘チェリー’, ‘バナナ’]

応用・注意点:現場で陥りやすい罠

1. 元の配列を変更してしまう
sort()は「破壊的メソッド」です。元の配列を直接書き換えるため、ReactのState管理などで使用すると意図しないバグを引き起こします。元の配列を保持したい場合は、スプレッド構文でコピーを作成するか、ES2023で導入されたtoSorted()を使用しましょう。

2. 比較関数の整合性
比較関数を書く際は、「反射的・反対称的・推移的」である必要があります。例えば、`a > b ? 1 : 0` のような不完全な条件分岐を書くと、ブラウザによってソート結果が異なる(あるいは全くソートされない)という問題が発生します。常に「正・負・0」のすべてが返り得る論理的な比較を行ってください。

3. 大規模なデータセット
ソート対象の要素数が膨大な場合、比較関数の中で重い処理を行うとパフォーマンスが低下します。その場合は、一度mapで必要な値だけを抽出してソートする手法(シュワルツ変換)の検討をおすすめします。

これらのポイントを押さえるだけで、配列操作の安定性は格段に向上します。ぜひ日々のコーディングに役立ててください。

コメント

タイトルとURLをコピーしました