JavaScriptで2つの数値配列の差分(偏差)を見つける方法
はじめに
本記事では、2つの数値配列を受け取り、どちらか片方にのみ存在する要素(共通しない要素)をすべて返すJavaScript関数の作成方法を解説します。これは「対称差(シンメトリックディファレンス)」と呼ばれる考え方で、配列同士を比較する際によく使われるテクニックです。
問題の例
たとえば、次のような2つの配列があったとします。
const arr1 = [2, 4, 2, 4, 6, 4, 3]; const arr2 = [4, 2, 5, 12, 4, 1, 3, 34];
この場合、期待される出力は次のようになります。
const output = [6, 5, 12, 1, 34];
両方の配列に存在する「2」「4」「3」は除外され、片方にしか存在しない要素だけが結果として返されます。
実装方法
アプローチのポイント
- 1つ目の配列を走査し、2つ目の配列に含まれていない要素を結果に追加する
- 2つ目の配列を走査し、1つ目の配列に含まれていない要素を結果に追加する
- 要素の存在確認には
indexOf()メソッドを使用する
サンプルコード
const arr1 = [2, 4, 2, 4, 6, 4, 3];
const arr2 = [4, 2, 5, 12, 4, 1, 3, 34];
const deviations = (first, second) => {
const res = [];
// first 側で、second に存在しない要素を収集
for (let i = 0; i < first.length; i++) {
if (second.indexOf(first[i]) === -1) {
res.push(first[i]);
}
}
// second 側で、first に存在しない要素を収集
for (let j = 0; j < second.length; j++) {
if (first.indexOf(second[j]) === -1) {
res.push(second[j]);
}
}
return res;
};
console.log(deviations(arr1, arr2));実行結果
コンソールには以下が出力されます。
[6, 5, 12, 1, 34]
補足:より簡潔な書き方
ES6以降では、filter() とスプレッド構文を使うことで、同じ処理をより宣言的に記述できます。
const deviations = (first, second) => [ ...first.filter(x => !second.includes(x)), ...second.filter(y => !first.includes(y)) ]; console.log(deviations(arr1, arr2)); // [6, 5, 12, 1, 34]
さらに重複を除去したい場合は、Set を組み合わせると便利です。
const uniqueDeviations = (first, second) => {
const set1 = new Set(first);
const set2 = new Set(second);
return [
...[...set1].filter(x => !set2.has(x)),
...[...set2].filter(y => !set1.has(y))
 ];
};
console.log(uniqueDeviations(arr1, arr2)); // [6, 5, 12, 1, 34]まとめ
2つの配列の差分(偏差)を求める基本的な方法は、片方の配列の各要素がもう片方に存在するかどうかを確認することです。小〜中規模の配列であれば indexOf() や includes() を使ったループ処理で十分ですが、大量のデータを扱う場合は Set を活用すると検索が O(1) になり、パフォーマンスが大幅に向上します。
-
JavaScriptで指定した間隔(ギャップ)を持つ2つの素数のペアを見つける方法
問題 数値 gap を第一引数として、また2つの数値からなる範囲配列を第二引数として受け取るJavaScript関数を作成する必要があります。この関数は、指定された範囲内に存在し、かつ絶対差が gap と一致する素数のペアを見つけて返すものです。 例えば、gap = 4、範囲が [20, 200] の場合、「37」と「41」はどちらも素数であり、その差はちょうど4であるため、条件を満たすペアとなります。 解決のアプローチ この問題は以下のステップで解決できます。 素数判定: 与えられた数が素数かどうかを判定するヘルパー関数を用意します。 素数の収集: 指定された範囲内のすべての素数を配列に
-
JavaScriptで2つの配列の合計を等しくする!要素交換アルゴリズムの解説
問題の概要数値を格納した2つの配列 arr1 と arr2 を、それぞれ第1引数・第2引数として受け取るJavaScript関数を実装することを考えます。ここで、arr1 の要素の合計と arr2 の要素の合計は互いに異なっています。この関数には次のような役割を持たせます。まず arr1 から1つの要素を取り出して arr2 へ移動させ、同時に arr2 から1つの要素を取り出して arr1 へ移動させます。この操作によって、両方の配列の要素の合計が等しくなるようにします。最後に、交換した2つの要素を配列として返します。例として、関数への入力が以下の場合を確認してみましょう。入力const a