JavaScriptでオブジェクトの配列をソートする
JavaScriptでオブジェクトの配列をソートする(比較関数ビルダー) | We.Inc
クリックだけで比較関数を作成できます。数値、文字列、日付、または2つのキーでオブジェクトを並べ替え、localeCompareのオプションも指定して、結果とコードを並べて確認しましょう。
JavaScriptでオブジェクトの配列をソートする
sortには、並べ替えたいプロパティを比べる比較関数を渡します。数値ならa.price - b.priceを返します。テキストならa.name.localeCompare(b.name)を返します。日付ならタイムスタンプを引き算します。結果が負ならaが先、正ならbが先になります。元の順序を残す必要があるときは、sortの代わりにtoSortedを使いましょう。
キーの種類ごとの比較関数
- 数値
- (a, b) => a.age - b.age
- (a, b) => b.age - a.age
- テキスト
- (a, b) => a.name.localeCompare(b.name)
- (a, b) => b.name.localeCompare(a.name)
- 数字を含むテキスト
- a.code.localeCompare(b.code, undefined, { numeric: true })
- aとbを入れ替える
- Dateオブジェクト
- (a, b) => a.joined - b.joined
- (a, b) => b.joined - a.joined
- ISO形式の日付文字列
- (a, b) => Date.parse(a.joined) - Date.parse(b.joined)
- aとbを入れ替える
- 真偽値(trueが先)
- (a, b) => Number(b.active) - Number(a.active)
- aとbを入れ替える
オブジェクトのソートでつまずく理由は3つあります。デフォルトのsortはすべてをテキストとして比較すること、単純な大小比較では大文字が小文字より先に並ぶこと、そしてsortは渡した配列そのものを書き換えることです。下のビルダーでは、小さなチームのリストでこれらのスイッチを1つずつ切り替えて順序の変化を確認でき、対応する比較関数もすぐにコピーできます。
- 並べ替えに使うプロパティを選びます:名前、年齢、開始日、または文字と数字が混ざったチケットコード。
- 昇順か降順を選び、テキストのキーでは単純な比較か、numericオプション付きのlocaleCompareかを選びます。
- 同順位を決めるために2つ目のキーを追加します。例えば、まずチーム、次に名前です。
- 生成されたコードをコピーします。表には、現在の比較関数で得られる順序が表示されます。
- 数値やオブジェクトに対して、関数なしでsort()を呼んではいけません。比較関数がないとすべての値が文字列に変換されるため、10が9より先に並び、オブジェクトはすべて[object Object]になります。
- trueやfalseではなく数値を返しましょう。真偽値の結果は1か0に変換され、順序が不安定になります。
- 長いリストをlocaleCompareでソートするなら、Intl.Collatorを1つ作ってそのcompareメソッドを渡しましょう。MDNによると、大きな配列ではそのほうが高速です。
- 値が欠けているレコードは、引き算の前にnullかどうかを調べるなどして、意図的に最後に置きましょう。そうしないとリストのあちこちに散らばります。
よくある質問
オブジェクトの配列をプロパティで並べ替えるには?
数値のプロパティならpeople.sort((a, b) => a.age - b.age)、文字列ならpeople.sort((a, b) => a.name.localeCompare(b.name))を呼びます。向きを逆にするにはaとbを入れ替えます。
2つのフィールドで並べ替えるには?
1つ目のフィールドを比較し、同順位のときだけ2つ目に進みます:(a, b) => a.team.localeCompare(b.team) || a.age - b.age。同順位は0を返し、0はfalseとして扱われるので||が機能します。
JavaScriptのsortは安定ですか?
はい。ECMAScript 2019以降、sortは安定でなければならないため、等しいと判定された要素は元の順序を保ちます。そのため、先に名前でソートしてからチームでソートすると、チームごとにまとまり、各グループ内では名前順になったリストが得られます。
sortは元の配列を変更しますか?
はい。sortは配列をその場で並べ替え、同じ配列を返します。toSortedは同じ比較関数を受け取りますが、新しい配列を返し、元の順序には手を付けません。2023年7月から主要なブラウザーすべてで使えます。
小文字の名前が大文字の後に並ぶのはなぜですか?
単純な<や>の比較は文字コードを比べ、どの大文字もどの小文字より小さいコードを持っているからです。localeCompareは言語のアルファベット順に従い、{ sensitivity: 'base' }を付けるとアクセントや大文字小文字の違いも同じものとして扱います。
比較関数が実際に返すもの
- sortが見るのは、返された数値の符号だけです。0未満ならaがbより前、0より大きければbが前、0ならそのままの順序を保ちます。数値の大きさは関係ないので、数値や日付では引き算が使えます。
- テキストでは'b' - 'a'がNaNになるため、引き算は使えません。localeCompareは文字列に対して負、0、正の数値を返すので、同じパターンにそのまま当てはめられます。
日付、欠けた値、混在した型
- Dateオブジェクトは引き算するとミリ秒の数値になるので、a.joined - b.joinedで古い順に並びます。ISO形式(2026-10-14)でテキストとして保存された日付も、年が先頭に来るためlocaleCompareで正しく並びますが、14/10/2026のような他の形式では正しく並びません。
- undefinedの要素は常に末尾に移動され、比較関数には渡されません。オブジェクトのプロパティがundefinedの場合は別で、そのオブジェクトは比較関数に渡されるので、自分でチェックする必要があります。
単純なsort()が数値を正しく並べられない理由
比較関数がないと、すべての要素が文字列に変換され、UTF-16のコード単位で比較されるため、最初の文字で順序が決まります。
デフォルトの順序と数値の比較関数の違い
テキストの'1'は'2'より前に来るので、デフォルトでは100が25より先に並びます。
複数キー、ロケール対応、元の配列を変更しないソート
チームをAからZ順、次に年長順、元の配列はそのまま
||の連鎖は、前の比較が0のときだけ次のキーに進みます。toSortedは新しい配列を返します。
長いリストにはIntl.Collatorを1つ
numeric: trueでT-2がT-10より前に並び、sensitivity: 'base'で大文字小文字とアクセントを無視します。
再利用できるsortByヘルパー
キー名を順番に渡します。キーの前にマイナス記号を付けると、そのキーは降順で並びます。
比較関数ビルダー
サンプルのチームリストの並べ方を選ぶと、表とコードが同時に更新されます。
並べ替えのキー
次のキー(同順位の決定)
なし
向き
昇順
降順
テキストの比較
単純な<と>
localeCompare
localeCompare、数値順で大文字小文字を区別しない
比較関数ビルダーで使うサンプルリスト(元の順序)
比較関数の結果
比較関数
コードをコピー
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る