0
0

JSON配列のキーの重複をチェックし、古いデータの方を削除する

Posted at

といった処理をしたかったのですが、こういったアルゴリズムっぽい話はChatGPTに聞くと割と一発でした。

やりたいこと

このようなデータがあり、groupIdが複数あった際にendDateが最新の方を残して古い方は削除したいです。

const data = [
  {
    groupId: 'po',
    classId: 'PO09',
    // その他のプロパティ...
    endDate: '2024-03-16'
  },
  {
    groupId: 'pds',
    classId: 'PDS06',
    // その他のプロパティ...
    endDate: '2024-01-20'
  },
  {
    groupId: 'po',
    classId: 'PO08',
    // その他のプロパティ...
    endDate: '2023-09-23'
  }
];

↑これを↓こうしたい

const data = [
  {
    groupId: 'po',
    classId: 'PO09',
    // その他のプロパティ...
    endDate: '2024-03-16'
  },
  {
    groupId: 'pds',
    classId: 'PDS06',
    // その他のプロパティ...
    endDate: '2024-01-20'
  }
];

以下のコードでできた

GPTさまさまです。

const data = [
  {
    groupId: 'po',
    classId: 'PO09',
    // その他のプロパティ...
    endDate: '2024-03-16'
  },
  {
    groupId: 'pds',
    classId: 'PDS06',
    // その他のプロパティ...
    endDate: '2024-01-20'
  },
  {
    groupId: 'po',
    classId: 'PO08',
    // その他のプロパティ...
    endDate: '2023-09-23'
  }
];

const result = Object.values(data.reduce((acc, item) => {
  const existingItem = acc[item.groupId];
  if (!existingItem || new Date(item.endDate) > new Date(existingItem.endDate)) {
    acc[item.groupId] = item;
  }
  return acc;
}, {}));

console.log(result);

解説ぽいもの (GPTくん)

GPT解説です。

ここでの主なタスクは、重複する groupId を持つ要素を特定し、それらの中から最新の endDate を持つ要素を選択することです。これを実現するために、Array.prototype.reduce メソッドを使用します。
reduce メソッドは配列の各要素に対して指定したリデューサー(コールバック関数)を実行し、単一の出力値(この場合はオブジェクト)を生成します。
このメソッドは2つのパラメータを取ります:リデューサー関数と初期値(ここでは空のオブジェクト {})。

const result = Object.values(data.reduce((acc, item) => {
  // リデューサー関数のロジック
}, {}));

リデューサー関数は、現在の要素(item)と累積値(acc)をパラメータとして受け取ります。
累積値 acc は、処理中に groupId をキーとして最新の要素を格納するオブジェクトです。
各ステップで、現在の要素の groupId が acc 内にすでに存在するかどうかをチェックします。存在する場合、その endDate と比較して、より新しい endDate を持つ要素を acc に保持します。
存在しない場合、現在の要素を acc に追加します。
reduce メソッドの実行後、acc には重複なしの groupId をキーとして、それぞれのグループの最新の要素が格納されています。
最終的に、Object.values() メソッドを使用して、acc オブジェクトの値のみを含む配列を取得し、これが最終結果となります。

const existingItem = acc[item.groupId];
if (!existingItem || new Date(item.endDate) > new Date(existingItem.endDate)) {
  acc[item.groupId] = item;
}

割とほかでも使えそうですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0