JavaScript で 2つの配列を重複せずに結合する
- ECMAScript 6 のスプレッド構文を使った JavaScript の配列のマージ
-
ECMAScript 5 の
Array.concat
関数を用いた JavaScript の配列マージ -
for
ループを使って配列から重複を削除する -
JavaScript による ECMAScript 6 の
Array.prototype
を用いた配列からの重複配列の削除 -
JavaScript で ECMAScript 5 で
Object.defineProperty
を使用して配列から重複要素を削除する -
Lo-Dash
またはUnderscore.js
を使用してマージし、一意の値のみを保持する -
ECMAScript 6 の
Set
を使ったマージとユニークな値のみの保持 -
O(n) だけの複雑さで
for
ループとDictionary
を使用して重複しない値をマージする
このチュートリアルでは、JavaScript で 2つの配列を重複せずにマージする方法を学びます。
まず、ES5 と ES6 の両方のバージョンで異なるマージ方法を紹介します。
次に、異なるメソッドを使用して重複を削除する方法を学びます。
最後に、独自の関数を書いたり、外部ライブラリを使ったりして、たった 1 ステップで操作を行う方法を学びます。
ここでは、2つの配列 arrayA
と arrayB
があり、それらを arrayC
にマージしたいとします。
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
var arrayC;
ECMAScript 6 のスプレッド構文を使った JavaScript の配列のマージ
スプレッド構文(...
)は、配列のような要素が想定される場所や、関数の中で 0 以上の引数が想定される場所などで、反復可能な要素の内容を展開するために使われます。
var arr = [2, 4];
function add(x, y) {
return x + y;
}
console.log(add(...arr));
では、このスプレッド構文を使って配列を arrayC
にマージしてみましょう。
arrayC = [...arrayA, ...arrayB];
console.log(arrayC);
コード例
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
var arrayC;
console.log("Array A > "+arrayA);
console.log("Array B > "+arrayB);
//merging using the spread syntax
arrayC = [...arrayA,...arrayB];
console.log("Merged Using Spread Syntax >"+arrayC);
出力:
Array A > Java,JavaScript
Array B > C#,PHP,Java
Merged Using Spread Syntax >Java,JavaScript,C#,PHP,Java
ECMAScript 5 の Array.concat
関数を用いた JavaScript の配列マージ
Array.concat
を用いた結合は、入力配列 ( arrayB
) の内容を元の配列 ( arrayA
) の内容と結合するために用いられます。
arrayC = arrayA.concat(arrayB);
console.log(arrayC);
結果の配列から重複しているものを削除したい場合は、複数の方法がありますので、その方法を見てみましょう。
例:
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
var arrayC;
console.log("Array A > "+arrayA);
console.log("Array B > "+arrayB);
//merging using Array.concat function in ECMAScript 5
arrayC = arrayA.concat(arrayB);
console.log("Merged Using Array.concat function >"+arrayC);
出力:
Array A > Java,JavaScript
Array B > C#,PHP,Java
Merged Using Array.concat function >Java,JavaScript,C#,PHP,Java
for
ループを使って配列から重複を削除する
重複を取り除く最も簡単な方法は、独自の入れ子になった for
ループを作成することです。
私たちのアルゴリズムは次のようになります。
- 入力配列
inArray
からクローンを作成し、元の配列を変更しないようにします。 arr.splice()
を使って重複している要素を見つけて削除するための入れ子ループを作成します。外側はn
から始まり、内側はn+1
から始まる。
function removeDuplicates(inArray) {
var arr =
inArray
.concat() // create a clone from inArray so not to change input array
// create the first cycle of the loop starting from element 0 or n
for (var i = 0; i < arr.length; ++i) {
// create the second cycle of the loop from element n+1
for (var j = i + 1; j < arr.length; ++j) {
// if the two elements are equal , then they are duplicate
if (arr[i] === arr[j]) {
arr.splice(j, 1); // remove the duplicated element
}
}
}
return arr;
}
そして、他の関数と同様に removeDuplicates
関数を使用することができます。
var arrayWithoutDuplicates = removeDuplicates(arrayC);
console.log(arrayWithoutDuplicates);
例:
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
var arrayC;
console.log("Array A > "+arrayA);
console.log("Array B > "+arrayB);
//removing duplicates from an array using nested for loop
function removeDuplicates(inArray){
var arr = inArray.concat() // create a clone from inArray so not to change input array
//create the first cycle of the loop starting from element 0 or n
for(var i=0; i<arr.length; ++i) {
//create the second cycle of the loop from element n+1
for(var j=i+1; j<arr.length; ++j) {
//if the two elements are equal , then they are duplicate
if(arr[i] === arr[j]) {
arr.splice(j, 1); //remove the duplicated element
}
}
}
return arr;
}
arrayC = arrayA.concat(arrayB);
console.log("Merged arrayC > "+ arrayC );
console.log("Removing duplicates using removeDuplicates > "+ removeDuplicates(arrayC) );
出力:
Array A > Java,JavaScript
Array B > C#,PHP,Java
Merged arrayC > Java,JavaScript,C#,PHP,Java
Removing duplicates using removeDuplicates > Java,JavaScript,C#,PHP
JavaScript による ECMAScript 6 の Array.prototype
を用いた配列からの重複配列の削除
ECMAScript 6 が使えるようになったら、Array.prototype
を使って重複を削除することもできます。
プロトタイプとは何を意味するのか?プロトタイプとは、JavaScript
におけるすべての関数やオブジェクトに関連付けられたオブジェクトのようなものです。
それでは、Array.prototype
をどのように使うか見てみましょう。
私たちのアルゴリズムは次のようになります。
- 配列オブジェクト
this.concat()
からクローンを作成し、元の配列を変更しないようにします。 arr.splice()
を用いて重複している要素を見つけて削除するための入れ子ループを作成します。外側はn
から始まり、内側はn+1
から始まる。
Array.prototype.removeDuplicates = function() {
var arr = this.concat(); // create a clone from the input so not to change
// the source
// create the first cycle of the loop starting from element 0 or n
for (var i = 0; i < arr.length; ++i) {
// create the second cycle of the loop from element n+1
for (var j = i + 1; j < arr.length; ++j) {
// if the two elements are equal , then they are duplicate
if (arr[i] === arr[j]) {
arr.splice(j, 1); // remove the duplicated element
}
}
}
return arr;
}
そして、そのプロトタイプを呼び出すと、次のようになります。
var arrayWithoutDuplicates = arrayC.removeDuplicates();
console.log(arrayWithoutDuplicates);
例
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
var arrayC;
console.log("Array A > "+arrayA);
console.log("Array B > "+arrayB);
arrayC = arrayA.concat(arrayB);
//removing duplicates from an array using Array.prototype in ECMAScript 6
Array.prototype.removeDuplicatesPrototype = function() {
var arr = this.concat(); // get the input array
//create the first cycle of the loop starting from element 0 or n
for(var i=0; i<arr.length; ++i) {
//create the second cycle of the loop from element n+1
for(var j=i+1; j<arr.length; ++j) {
//if the two elements are equal , then they are duplicate
if(arr[i] === arr[j]) {
arr.splice(j, 1); //remove the duplicated element
}
}
}
return arr;
}
console.log("Merged arrayC > "+arrayC);
console.log("Removing duplicates using removeDuplicatesPrototype > "+arrayC.removeDuplicatesPrototype());
JavaScript で ECMAScript 5 で Object.defineProperty
を使用して配列から重複要素を削除する
ECMAScript 5 しか使えないのであれば、Object.defineProperty
を使って独自のプロパティを作成すれば、Array
型のすべての要素から重複を取り除くことができます。
ここでは、Array.prototype
と入力してプロパティの型を配列のプロトタイプとして定義します。プロパティの名前は removeDuplicates
のように次のパラメータとして挿入する必要があります。
どのように正しく書かれているか見てみましょう。
Object.defineProperty(Array.prototype, 'removeDuplicates', {
// defining the type and name of the property
enumerable: false,
configurable: false,
writable: false,
value: function() {
var arr = this.concat(); // get the input array
// create the first cycle of the loop starting from element 0 or n
for (var i = 0; i < arr.length; ++i) {
// create the second cycle of the loop from element n+1
for (var j = i + 1; j < arr.length; ++j) {
// if the two elements are equal , then they are duplicate
if (arr[i] === arr[j]) {
arr.splice(j, 1); // remove the duplicated element
}
}
}
return arr;
}
});
このようにしてプロパティを直接呼び出すことができます。
var arrayWithoutDuplicates = arrayC.removeDuplicates();
console.log(arrayWithoutDuplicates);
例
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
var arrayC;
console.log("Array A > "+arrayA);
console.log("Array B > "+arrayB);
arrayC = arrayA.concat(arrayB);
//removing duplicates from an array using defineProperty in ECMAScript 5
Object.defineProperty(Array.prototype, 'removeDuplicatesProperty', { //defining the type and name of the property
enumerable: false,
configurable: false,
writable: false,
value: function() {
var arr = this.concat(); // get the input array
//create the first cycle of the loop starting from element 0 or n
for(var i=0; i<arr.length; ++i) {
//create the second cycle of the loop from element n+1
for(var j=i+1; j<arr.length; ++j) {
//if the two elements are equal , then they are duplicate
if(arr[i] === arr[j]) {
arr.splice(j, 1); //remove the duplicated element
}
}
}
return arr;
}
});
console.log("Merged arrayC > "+arrayC);
console.log("Removing duplicates using removeDuplicatesProperty > "+arrayC.removeDuplicatesProperty() );
Lo-Dash
または Underscore.js
を使用してマージし、一意の値のみを保持する
2つ以上の配列からユニークな値の新しい配列を取得して外部ファイルを利用することが目的であれば、Lo-Dash
ライブラリを利用することができます。
まず、HTML テンプレート内の Cloudflare CDN
を使ってライブラリをインポートする必要があります。
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
そして、ライブラリのようなものを使用します。
arrayC = _.union(arrayA, arrayB);
例:
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
console.log('Array A > ' + arrayA);
console.log('Array B > ' + arrayB);
// merging arrayA and arrayB keeping only unique values using Lo-Dash library
// don't forget to import the script using <script
// src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
console.log(
'Merging arrayA and arrayB keeping only unique values using Lo-Dash Lib. > ' +
_.union(arrayA, arrayB));
ECMAScript 6 の Set
を使ったマージとユニークな値のみの保持
ECMAScript 6 が使えて、ターゲットが複数の配列のユニークな値だけであれば、Set
は非常に良い選択肢となります。
以下の例のように spread
構文を使って使うことができます。
arrayC = [...new Set([...arrayA, ...arrayB])];
あるいは、次のように使うこともできます。
arrayC = Array.from(new Set(arrayA.concat(arrayB)));
例:
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
console.log('Array A > ' + arrayA);
console.log('Array B > ' + arrayB);
// merging arrayA and arrayB keeping unique values using Set in ECMAScript 6
console.log(
'Merging arrayA and arrayB keeping only unique values using Set > ' +
Array.from(new Set(arrayA.concat(arrayB))));
console.log(
'Merging arrayA and arrayB keeping only unique values using Set with spread syntax > ' +
[...new Set([...arrayA, ...arrayB])]);
O(n) だけの複雑さで for
ループと Dictionary
を使用して重複しない値をマージする
2つの配列をマージして重複した値を持たずに結果を得るもう一つの方法は、JavaScript
の Dictionary
の考え方を利用することです。
function mergeAndGetUnique(arrayA, arrayB) {
var hash = {};
var x;
for (x = 0; i < arrayA.length; i++) {
hash[arrayA[i]] = true;
}
for (x = 0; i < arrayB.length; i++) {
hash[arrayB[i]] = true;
}
return Object.keys(hash);
}
そうすれば、このような関数を使用することができます。
arrayC = mergeAndGetUnique(arrayA, arrayB);
例
var arrayA = ['Java', 'JavaScript'];
var arrayB = ['C#', 'PHP', 'Java'];
var arrayC;
console.log("Array A > "+arrayA);
console.log("Array B > "+arrayB);
arrayC = arrayA.concat(arrayB);
//merging arrayA and arrayB keeping unique values using dictionary with O(n) complexity
function mergeAndGetUnique(arrayA, arrayB) {
var hash = {};
var x;
for (x = 0; x < arrayA.length; x++) {
hash[arrayA[x]] = true;
}
for (x = 0; x < arrayB.length; x++) {
hash[arrayB[x]] = true;
}
return Object.keys(hash);
}
console.log("Merging arrayA and arrayB keeping only unique values using Set with spread syntax > "+ mergeAndGetUnique(arrayA, arrayB) );