【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 ]
コードの解説
このコードの動作を順を追って見ていきましょう。
- filter() メソッドが、arr1 の各要素(el)に対してコールバック関数を実行します。
- コールバック内の find() メソッドは、arr2 の中から identifier プロパティが el と一致するオブジェクトを探します。
- 一致するオブジェクトが見つからない場合、find() は undefined を返します。
- その結果を !(論理否定)で反転させることで、「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 を活用した実装を検討するとよいでしょう。
-
JavaScriptのArray.values()メソッドとは?使い方とサンプルコードを徹底解説
JavaScriptのArray.values()メソッドとは? JavaScriptのArray.values()メソッドは、対象の配列に含まれるすべての値を格納したイテレーターオブジェクトを返します。ES2015(ES6)以降で利用可能なこのメソッドは、for...ofループやスプレッド構文([...arr])と組み合わせることで、配列の各要素を効率的に取り出せます。 なお、keys()やentries()がインデックス情報も一緒に返すのに対し、values()は純粋に「値」だけを順番に提供する点が大きな特徴です。 基本構文 arr.values() 引数は不要で、戻り値として新しいArr
-
JavaScript配列から一意の値(重複なし)を取得する方法
JavaScriptの配列に含まれる重複した値を取り除き、一意の値(ユニークな値)だけを取得したい場合は、Setオブジェクトを使うのが最もシンプルで効率的な方法です。 Setは同じ値を1つしか格納できないデータ構造のため、配列をnew Set()に渡すだけで自動的に重複が排除されます。その後、スプレッド構文([...set])を使えば、簡単に元の配列形式へ戻すことができます。 サンプルコード 以下は、JavaScriptの配列からすべての一意の値を取得する実際のコード例です。 <!DOCTYPE html> <html lang=ja> <head> <