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

JavaScriptでオブジェクトの配列を比較する方法|IDの存在チェックを実装

問題の概要

次のように、2つのオブジェクトの配列があったとします。

const blocks = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
  { id: 4 },
];
const containers = [
  { block: { id: 1 } },
  { block: { id: 2 } },
  { block: { id: 3 } },
];

ここで必要となるのは、blocks 配列の各オブジェクトが持つ id が、containers 配列内の各オブジェクトの block.id としてすべて存在するかどうかをチェックする関数です。blocks 側に containers に存在しない id がひとつでもあれば false を返し、すべて存在していれば true を返します。

実装例

まずは基本的な for ループを使った書き方を見てみましょう。

const blocks = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
  { id: 4 },
];
const containers = [
  { block: { id: 1 } },
  { block: { id: 2 } },
  { block: { id: 3 } },
];

const checkProperty = (first, second) => {
  const findInContainers = id => {
    for (let i = 0; i < second.length; i++) {
      if (second[i].block.id === id) {
        return true;
      }
    }
    return false;
  };
  for (let i = 0; i < first.length; i++) {
    if (!findInContainers(first[i].id)) {
      return false;
    }
  }
  return true;
};

console.log(checkProperty(blocks, containers));

出力結果

コンソールには次のように表示されます。

false

この例では blocks{ id: 4 }containers 側に存在しないため、false が返されています。

コードの解説

  • findInContainers 関数: 引数で受け取った idcontainers 配列内に存在するかを先頭から順に調べ、見つかれば true、最後まで見つからなければ false を返します。
  • 外側のループ: blocks の各 idfindInContainers に渡して確認し、ひとつでも見つからなければその時点で false を返して処理を終了します。
  • 最終的な戻り値: すべての id の存在が確認できた場合のみ true を返します。

より簡潔な書き方:some と every を活用

Array.prototype.everyArray.prototype.some を組み合わせると、同じ処理をより宣言的で読みやすいコードで表現できます。

const checkProperty = (first, second) =>
  first.every(block =>
    second.some(container => container.block.id === block.id)
  );

console.log(checkProperty(blocks, containers)); // false

every は「すべての要素が条件を満たす場合に true」、some は「ひとつでも条件を満たす要素があれば true」を返すため、ネストした for ループや途中脱出のロジックを自分で書く必要がありません。

パフォーマンスを重視するなら Set が便利

データ件数が多い場合は、あらかじめ containers 側の ID を Set に格納しておくと、存在確認が O(1) となり処理速度が大幅に向上します。

const checkPropertyWithSet = (first, second) => {
  const ids = new Set(second.map(c => c.block.id));
  return first.every(b => ids.has(b.id));
};

console.log(checkPropertyWithSet(blocks, containers)); // false

状況に応じて、可読性を優先するなら some/every 版、パフォーマンスを優先するなら Set 版を選ぶとよいでしょう。

  1. JavaScriptのオブジェクト配列に配列メソッドを適用する方法

    JavaScriptでは、オブジェクトが格納された配列に対しても、通常の配列と同じようにpop()、push()、splice()などの標準的な配列メソッドをそのまま使用できます。オブジェクト配列はあくまで「配列」であるため、要素としてオブジェクトが入っていても配列操作のAPIは共通で動作します。 コード例 以下は、JavaScriptオブジェクトの配列に対して配列メソッドを使用するサンプルコードです。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8

  2. JavaScriptでフラットなオブジェクト配列をツリー構造に変換する方法

    はじめにWeb開発では、カテゴリ一覧やフォルダ構成、組織図など、階層構造をもつデータを画面に表示したい場面がよくあります。一方で、データベースやAPIから取得したデータは、idとparentIdを持つフラット(一次元)な配列として渡されることがほとんどです。本記事では、こうしたフラットな配列をもとに、子要素を親オブジェクトへリンクさせたツリー構造を組み立て、ネストされたリスト形式で画面に表示するまでの手順を、HTML・CSSのコード付きでわかりやすく解説します。元データとなるフラットな配列まず、変換対象となるデータを確認しましょう。各オブジェクトは、自身の一意な識別子であるid、表示名のnam