JavaScriptで2つの配列をマージして重複を削除する方法
課題
JavaScriptで、2つの数値の配列 arr1 と arr2 を引数として受け取る関数を作成することを考えます。
この関数は、両方の配列の要素を1つの新しい配列にマージします。マージの前後いずれかの時点で重複する要素が存在した場合には、余分なコピーを削除し、各要素が必ず1回だけ現れるようにしなければなりません。
要素の並び順は厳密には問われませんが、各要素の出現回数(必ず1回であること)が重要なポイントになります。
入力例
const arr1 = [6, 5, 2, 1, 8];
const arr2 = [3, 4, 6, 8, 9];
この場合、期待される出力は次のとおりです。
const output = [6, 5, 2, 1, 8, 3, 4, 9];
6 と 8 は両方の配列に含まれていますが、結果にはそれぞれ1回しか登場していません。
実装コード
以下は、ループ処理と includes() メソッドを組み合わせた基本的な実装例です。
const arr1 = [6, 5, 2, 1, 8];
const arr2 = [3, 4, 6, 8, 9];
const mergeAndRectify = (arr1 = [], arr2 = []) => {
const { length: len1 } = arr1;
const { length: len2 } = arr2;
const res = [];
// arr1 の要素を順に追加(重複はスキップ)
for (let i = 0; i < len1; i++) {
if (!res.includes(arr1[i])) {
res.push(arr1[i]);
}
}
// arr2 の要素を順に追加(重複はスキップ)
for (let i = 0; i < len2; i++) {
if (!res.includes(arr2[i])) {
res.push(arr2[i]);
}
}
return res;
};
console.log(mergeAndRectify(arr1, arr2));
出力
[ 6, 5, 2, 1, 8, 3, 4, 9 ]
まず arr1 のすべての要素が新しい配列に追加され、続いて arr2 の要素のうち、まだ存在しないものだけが追加されます。その結果、6 と 8 の重複が自動的に排除され、各要素が1回だけ含まれる配列が完成します。
Set を使ったより簡潔な方法
ES2015以降では、Set オブジェクトを使うことで、同じ処理をわずか1行で実現できます。Setは重複する値を保持しないため、重複除去に最適です。
const mergeAndRectify = (arr1, arr2) => [...new Set([...arr1, ...arr2])];
スプレッド構文で両方の配列を展開して新しいSetを作成し、それを再度スプレッド構文で配列に戻しています。コードが劇的に短くなるため、実務でも広く使われるイディオムです。
パフォーマンスに関する注意点
includes() を使う方法は直感的で理解しやすい反面、判定のたびに線形探索が行われるため、計算量は O(n²) になります。一方、Set を使う方法は内部的にハッシュテーブルを利用するため O(n) で動作し、要素数の多い配列を扱う場合に大きく有利です。
特別な理由がない限り、実際の開発では Set ベースのアプローチを選ぶことをおすすめします。
-
JavaScriptのconst宣言とは?再代入できない変数の基本と使い方を解説
JavaScriptのconst宣言は、値を再代入することも後から再宣言することもできない変数を作成するための構文です。constはES2015(ES6)で導入されました。 const宣言の主な特徴 一度値を代入すると、別の値に再代入することはできません。 同じ名前の変数を同じスコープ内で再宣言するとエラーになります。 宣言時に必ず初期値を代入する必要があります。 ブロックスコープ({}内でのみ有効)を持ちます。 それでは、JavaScriptにおけるconst宣言の実際のコードを見ていきましょう。 サンプルコード <!DOCTYPE html> <html>
-
JavaScriptで数式を英単語の読み方に変換する関数の実装方法
問題 数式を表す文字列(例:「5 - 8」)を受け取り、その式を英語の単語による読み方(例:「Five Minus Eight」)に変換して返すJavaScript関数を作成します。 対応する演算子は以下の通りです。 + : Plus(足す) - : Minus(引く) * : Times(掛ける) / : Divided By(割る) ** : To The Power Of(累乗) = : Equals(等しい) != : Does Not Equal(等しくない) 扱う数値は1から10までです。もし入力された演算子が上記のリストに存在しない場合は、「Thats not an ope