JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

プロパティに一貫性がないJavaScriptオブジェクト配列を柔軟に並べ替える方法

実務では、同じ配列の中に「あるプロパティを持つオブジェクト」と「持たないオブジェクト」が混在することがよくあります。ここでは、一部のオブジェクトだけが date フィールド(サーバーから文字列として返される値であり、Date オブジェクトではありません)を持ち、残りのオブジェクトではこのフィールドが null になっているケースを例に、条件に応じた柔軟なソート処理を紹介します。

やりたいこと(要件の整理)

  • 日付を持たないオブジェクトを先頭に表示する
  • 日付を持つオブジェクトは、その後ろに日付の昇順(古い順)で表示する
  • 日付を持たないオブジェクト同士は、name フィールドなどを基準にアルファベット順で並べる

実装例:カスタムコンパレータ関数

const sorter = ((a, b) => {
    if (typeof a.date == 'undefined' && typeof b.date != 'undefined') {
        return -1;
    }
    else if (typeof a.date != 'undefined' && typeof b.date == 'undefined') {
        return 1;
    }
    else if (typeof a.date == 'undefined' && typeof b.date == 'undefined') {
        return a.name.localeCompare(b.name);
    }
    else if (a.date == null && b.date != null) {
        return -1;
    }
    else if (a.date != null && b.date == null) {
        return 1;
    }
    else if (a.date == null && b.date == null) {
        return 0;
    }
    else {
        var d1 = Date.parse(a.date);
        var d2 = Date.parse(b.date);
        return d1 - d2;
    }
});

コードのポイント解説

このコンパレータ関数は、Array.prototype.sort() に渡して使用します。比較ロジックは以下の順序で判定されます。

  1. date プロパティの存在チェック(typeof):片方だけプロパティが存在する場合、-1 を返すことで存在しない側を先頭に移動させます。
  2. 両方とも存在しない場合a.name.localeCompare(b.name) によって、名前のアルファベット順で比較します。
  3. null チェック:プロパティ自体は存在するものの値が null のケースを判定し、こちらも日付なしを先頭に配置します。
  4. 両方に日付がある場合Date.parse() で日付文字列をミリ秒数値に変換し、その差分を返すことで日付の昇順ソートを実現します。

動作確認用のサンプルデータ

const data = [
  { name: 'Banana', date: '2023-05-01' },
  { name: 'Apple',  date: null },
  { name: 'Cherry', date: '2023-01-15' },
  { name: 'Orange' } // date プロパティ自体が存在しない
];

data.sort(sorter);

console.log(data);
// 出力順: Apple → Orange(日付なし・名前順)
//         → Cherry → Banana(日付の古い順)

補足:より安全に使うためのヒント

  • sort() は元の配列を破壊的に変更します。元の配列を保持したい場合は [...data].sort(sorter) のようにコピーを作成するか、ES2023 以降で利用可能な toSorted() を活用しましょう。
  • Date.parse() の代わりに new Date(a.date).getTime() を使っても同じ結果が得られます。
  • 日付文字列は ISO 8601 形式(例: YYYY-MM-DD)であれば、ブラウザ間の差異なく確実にパースできます。
  • localeCompare() はロケールを考慮した比較が可能なため、日本語の五十音順ソートへの応用も容易です。
  1. JavaScriptで日付の「日」を設定する方法|setDate()の使い方を解説

    JavaScriptでは、DateオブジェクトのsetDate()メソッドを使うことで、日付の「日」(1〜31)を設定・変更できます。この記事では、実際のコード例と実行結果をもとに、setDate()の基本的な使い方をわかりやすく解説します。 setDate()メソッドとは setDate()は、Dateオブジェクトの「日」の値だけを変更するためのメソッドです。年や月はそのままに、日にちだけを差し替えたい場合に便利です。引数には1〜31の整数を指定しますが、範囲外の値を渡してもエラーにはならず、自動的に月をまたいだ日付へと調整されます。また、このメソッドは元のDateオブジェクト自体を書き換え

  2. JavaScriptでDateオブジェクトを作成する方法をわかりやすく解説

    JavaScriptで日付や時刻を扱うには、Dateオブジェクトを使用します。new Date()コンストラクタを呼び出すだけで、現在の日時に基づいたDateオブジェクトを簡単に生成できます。以下に、ボタンをクリックすると現在の日時を持つDateオブジェクトを作成し、画面に表示するサンプルコードを示します。コード例<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport"