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

【JavaScript】別の配列(オブジェクト)に存在しない値だけを抽出する方法

問題の概要

次の2つの配列(arr1 と arr2)が与えられたとします。

  • arr1:いくつかのリテラル値(数値など)が格納された配列
  • arr2:一部のリテラル値を identifier プロパティとして持つオブジェクトの配列

ここで求められているのは、この2つの配列を引数として受け取るJavaScript関数を作成することです。作成する関数は、arr2 内のオブジェクトに含まれていない(マッピングされていない)arr1 の要素だけを抽出し、新しい配列として返す必要があります。

実装コード

この問題は、Array.prototype.filter() メソッドと Array.prototype.find() メソッドを組み合わせることで、シンプルに解決できます。

const arr1 = [111, 222, 333, 444];
const arr2 = [
    { identifier: 111 },
    { identifier: 222 },
    { identifier: 444 },
];
const getAbsentValues = (arr1, arr2) => {
    let res = [];
    res = arr1.filter(el => {
        return !arr2.find(obj => {
            return el === obj.identifier;
        });
    });
    return res;
};
console.log(getAbsentValues(arr1, arr2));

出力結果

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

[ 333 ]

コードの解説

このコードの動作を順を追って見ていきましょう。

  1. filter() メソッドが、arr1 の各要素(el)に対してコールバック関数を実行します。
  2. コールバック内の find() メソッドは、arr2 の中から identifier プロパティが el と一致するオブジェクトを探します。
  3. 一致するオブジェクトが見つからない場合、find() は undefined を返します。
  4. その結果を !(論理否定)で反転させることで、「arr2 に存在しない要素」のみが true と評価され、結果の配列に残ります。

この例では、333 だけが arr2 のどのオブジェクトにもマッピングされていないため、結果は [ 333 ] となります。

パフォーマンスを改善する代替案

上記の方法は直感的で読みやすい一方、filter() の各要素ごとに find() が arr2 を先頭から走査するため、計算量は O(n × m) になります。データ量が多い場合は、Set を使うことで O(n + m) まで高速化できます。

const getAbsentValues = (arr1, arr2) => {
    const identifiers = new Set(arr2.map(obj => obj.identifier));
    return arr1.filter(el => !identifiers.has(el));
};

まず arr2 の identifier の値をすべて Set に集め、その後 filter() 内では Set の has() メソッドによる O(1) の存在判定を行います。大量のデータを扱う場合に特に有効なアプローチです。

まとめ

配列とオブジェクト配列の差分を取得したい場合は、filter() と find() の組み合わせが最もシンプルな解決策です。ただし、パフォーマンスが重要な場面では、Set を活用した実装を検討するとよいでしょう。

  1. JavaScriptのArray.values()メソッドとは?使い方とサンプルコードを徹底解説

    JavaScriptのArray.values()メソッドとは? JavaScriptのArray.values()メソッドは、対象の配列に含まれるすべての値を格納したイテレーターオブジェクトを返します。ES2015(ES6)以降で利用可能なこのメソッドは、for...ofループやスプレッド構文([...arr])と組み合わせることで、配列の各要素を効率的に取り出せます。 なお、keys()やentries()がインデックス情報も一緒に返すのに対し、values()は純粋に「値」だけを順番に提供する点が大きな特徴です。 基本構文 arr.values() 引数は不要で、戻り値として新しいArr

  2. JavaScript配列から一意の値(重複なし)を取得する方法

    JavaScriptの配列に含まれる重複した値を取り除き、一意の値(ユニークな値)だけを取得したい場合は、Setオブジェクトを使うのが最もシンプルで効率的な方法です。 Setは同じ値を1つしか格納できないデータ構造のため、配列をnew Set()に渡すだけで自動的に重複が排除されます。その後、スプレッド構文([...set])を使えば、簡単に元の配列形式へ戻すことができます。 サンプルコード 以下は、JavaScriptの配列からすべての一意の値を取得する実際のコード例です。 <!DOCTYPE html> <html lang=ja> <head> <