web-dev-qa-db-ja.com

2つの配列をJavaScriptでマージして項目を重複排除する方法

2つのJavaScript配列があります。

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

出力を次のようにします。

var array3 = ["Vijendra","Singh","Shakya"];

出力配列から繰り返し単語を削除する必要があります。

2つの配列をJavaScriptでマージして、元の配列に挿入されたのと同じ順序で各配列から一意の項目のみを取得する方法を教えてください。

1090
Vijjendra

(重複を削除せずに)配列をマージするだけ

ES5バージョンはArray.concatを使用します。

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var array3 = array1.concat(array2); // Merges both arrays
// [ 'Vijendra', 'Singh', 'Singh', 'Shakya' ]

ES6版使用 デストラクタリング

const array1 = ["Vijendra","Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = [...array1, ...array2];

重複を削除するための「組み込み」の方法はありません( ECMA-262 実際にはArray.forEachがありますが、これは非常に便利です)。

Array.prototype.unique = function() {
    var a = this.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
};

それを使うには:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
// Merges both arrays and gets unique items
var array3 = array1.concat(array2).unique(); 

これにより、配列の順序も保持されます(つまり、ソートは不要)。

多くの人がArray.prototypeおよびfor inループのプロトタイプ増強に悩まされているので、これを使用するためのより侵襲的でない方法は次のとおりです。

function arrayUnique(array) {
    var a = array.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(a[i] === a[j])
                a.splice(j--, 1);
        }
    }

    return a;
}

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
    // Merges both arrays and gets unique items
var array3 = arrayUnique(array1.concat(array2));

ES5が利用可能なブラウザで動作するのに十分幸運な人のために、あなたはこのようにObject.definePropertyを使うことができます:

Object.defineProperty(Array.prototype, 'unique', {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function() {
        var a = this.concat();
        for(var i=0; i<a.length; ++i) {
            for(var j=i+1; j<a.length; ++j) {
                if(a[i] === a[j])
                    a.splice(j--, 1);
            }
        }

        return a;
    }
});
1370
LiraNuna

Underscore.jsまたはLo-Dashを使えば、次のことができます。

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

http://underscorejs.org/#union

http://lodash.com/docs#union

533
GijsjanB

まず2つの配列を連結し、次に固有の項目だけを除外します。

var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b);
var d = c.filter(function (item, pos) {return c.indexOf(item) == pos});

// d is [1,2,3,101,10]

http://jsfiddle.net/simo/98622/

編集する

@Dmitry(下記の2番目のコメントを参照)によって示唆されているように、よりパフォーマンス的な解決策はbと連結する前にa内のユニークな項目を除外することです

var a = [1, 2, 3], b = [101, 2, 1, 10];
var c = a.concat(b.filter(function (item) {
    return a.indexOf(item) < 0;
}));

// d is [1,2,3,101,10]
220
simo

これは スプレッド演算子 および配列総称を使用したECMAScript 6のソリューションです。

現時点ではFirefoxと、おそらくInternet Explorer Technical Previewでしか動作しません。

しかし、 Babel を使えば、今すぐ入手できます。

// Input: [ [1, 2, 3], [101, 2, 1, 10], [2, 1] ]
// Output: [1, 2, 3, 101, 10]
function mergeDedupe(arr)
{
  return [...new Set([].concat(...arr))];
}
140
Adria

ES6

array1.Push(...array2) // => don't remove duplication 

OR

[...array1,...array2] //   =>  don't remove duplication 

OR

[...new Set([...array1 ,...array2])]; //   => remove duplication
113
Abdennour TOUMI

Set (ECMAScript 2015)を使用すると、それはそれと同じくらい簡単になります。

const array1 = ["Vijendra", "Singh"];
const array2 = ["Singh", "Shakya"];
const array3 = Array.from(new Set(array1.concat(array2)));
46

ここでは、少し異なるループについて説明します。最新バージョンのChromeでの最適化によっては、2つの配列の和集合を解決するための最速の方法です(Chrome 38.0.2111)。

http://jsperf.com/merge-two-arrays-keeping-only-unique-values

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [];

var arr = array1.concat(array2),
  len = arr.length;

while (len--) {
  var itm = arr[len];
  if (array3.indexOf(itm) === -1) {
    array3.unshift(itm);
  }
}

whileループ:〜589k ops/s 
フィルター:〜445k ops/s 
lodash:308k ops/s 
ループ用:225k ops/s

コメントは、私の設定変数の1つが、書き込みのために空の配列を初期化する必要がないため、ループが他のループよりも先に進むことを引き起こしていることを指摘しました。私はそれに同意するので、私は競技場にもテストを書き換えて、さらに速いオプションを含めました。

http://jsperf.com/merge-two-arrays-keeping-only-unique-values/52

let whileLoopAlt = function (array1, array2) {
    const array3 = array1.slice(0);
    let len1 = array1.length;
    let len2 = array2.length;
    const assoc = {};

    while (len1--) {
        assoc[array1[len1]] = null;
    }

    while (len2--) {
        let itm = array2[len2];

        if (assoc[itm] === undefined) { // Eliminate the indexOf call
            array3.Push(itm);
            assoc[itm] = null;
        }
    }

    return array3;
};

この代替ソリューションでは、1つの回答の連想配列ソリューションを組み合わせてループ内の.indexOf()呼び出しを排除しました。2つ目のループで処理が大幅に遅くなり、他のユーザーが回答として提案したその他の最適化も含まれます。そうですね。

すべての値(i-1)に対する二重ループを使用したここでの一番の答えは、まだかなり遅いです。 lodashはまだ力強い活動をしています、そして私はまだ彼らのプロジェクトにライブラリを追加することを気にしない人にはそれをお勧めします。したくない人のために、私のwhileループはまだ良い答えであり、フィルターの答えはここで非常に強い結果を示しており、この記事を書いている時点で最新のCanary Chrome(44.0.2360)ですべてを打ち負かしました。

マイクの答え および ダン・ストッカーの答え スピードを一段階上げたい場合は/をチェックしてください。ほとんどすべての実行可能な答えを調べた後、これらははるかにすべての結果の中で最速です。

33
slickplaid

ECMAScript 6を使えば簡単にできます。

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
  • スプレッド演算子 を使用して配列を連結します。
  • Set を使用して、個別の要素セットを作成します。
  • 再びSet演算子を配列に変換するために、スプレッド演算子を使います。
Array.prototype.merge = function(/* variable number of arrays */){
    for(var i = 0; i < arguments.length; i++){
        var array = arguments[i];
        for(var j = 0; j < array.length; j++){
            if(this.indexOf(array[j]) === -1) {
                this.Push(array[j]);
            }
        }
    }
    return this;
};

はるかに優れた配列マージ機能 

16
GAgnew

2つの配列をマージし、es6の重複を削除する 

let arr1 = [3, 5, 2, 2, 5, 5];
let arr2 = [2, 1, 66, 5];
let unique = [...new Set([...arr1,...arr2])];
console.log(unique);
// [ 3, 5, 2, 1, 66 ]
15
Yin Gong

入れ子になったループ(O(n ^ 2))と.indexOf()(+ O(n))を避けてください。

function merge(a, b) {
    var hash = {}, i;
    for (i=0; i<a.length; i++) {
        hash[a[i]]=true;
    } 
    for (i=0; i<b.length; i++) {
        hash[b[i]]=true;
    } 
    return Object.keys(hash);
}
14
Dan Stocker

私の2セントを投げ込むだけです。

function mergeStringArrays(a, b){
    var hash = {};
    var ret = [];

    for(var i=0; i < a.length; i++){
        var e = a[i];
        if (!hash[e]){
            hash[e] = true;
            ret.Push(e);
        }
    }

    for(var i=0; i < b.length; i++){
        var e = b[i];
        if (!hash[e]){
            hash[e] = true;
            ret.Push(e);
        }
    }

    return ret;
}

これは私がよく使う方法です。重複チェックをするためにハッシュルックアップテーブルとしてオブジェクトを使います。ハッシュがO(1)であると仮定すると、これはO(n)で実行されます。ここで、nはa.length + b.lengthです。私はブラウザがどのようにハッシュを行うのか正直にはわかりませんが、何千ものデータポイントでうまく機能します。

14
Mike

どうしてオブジェクトを使わないの?セットをモデル化しようとしているようです。しかし、これは順番を保存しません。

var set1 = {"Vijendra":true, "Singh":true}
var set2 = {"Singh":true,  "Shakya":true}

// Merge second object into first
function merge(set1, set2){
  for (var key in set2){
    if (set2.hasOwnProperty(key))
      set1[key] = set2[key]
  }
  return set1
}

merge(set1, set2)

// Create set from array
function setify(array){
  var result = {}
  for (var item in array){
    if (array.hasOwnProperty(item))
      result[array[item]] = true
  }
  return result
}
13
Nick Retallack

私の一人半ペニー:

Array.prototype.concat_n_dedupe = function(other_array) {
  return this
    .concat(other_array) // add second
    .reduce(function(uniques, item) { // dedupe all
      if (uniques.indexOf(item) == -1) {
        uniques.Push(item);
      }
      return uniques;
    }, []);
};

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var result = array1.concat_n_dedupe(array2);

console.log(result);
8
Hero Qu

最善の解決策.

あなたが押すことによってブラウザコンソールで直接チェックすることができます...

重複なし

a = [1, 2, 3];
b = [3, 2, 1, "prince"];

a.concat(b.filter(function(el) {
    return a.indexOf(el) === -1;
}));

重複して

["prince", "asish", 5].concat(["ravi", 4])

あなたが重複しないで欲しいならば、あなたはここからより良い解決策を試すことができます - Shouting Code

[1, 2, 3].concat([3, 2, 1, "prince"].filter(function(el) {
    return [1, 2, 3].indexOf(el) === -1;
}));

Chromeブラウザコンソールで試す

 f12 > console

出力:

["prince", "asish", 5, "ravi", 4]

[1, 2, 3, "prince"]
8
Zigri2612

単純化された simoの答え そしてそれをNice関数に変えました。

function mergeUnique(arr1, arr2){
    return arr1.concat(arr2.filter(function (item) {
        return arr1.indexOf(item) === -1;
    }));
}
8
Andrew

Underscore.jsの=> uniq を使って簡単に実現できます。

array3 = _.uniq(array1.concat(array2))

console.log(array3)

["Vijendra"、 "Singh"、 "Shakya"] と表示されます。

//Array.indexOf was introduced in javascript 1.6 (ECMA-262) 
//We need to implement it explicitly for other browsers, 
if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt, from)
  {
    var len = this.length >>> 0;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}
//now, on to the problem

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var merged = array1.concat(array2);
var t;
for(i = 0; i < merged.length; i++)
  if((t = merged.indexOf(i + 1, merged[i])) != -1)
  {
    merged.splice(t, 1);
    i--;//in case of multiple occurrences
  }

他のブラウザ用のindexOfメソッドの実装は _ mdc _ からとられています

6
Amarghosh

Setを使って行うことができます。

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var array3 = array1.concat(array2);
var tempSet = new Set(array3);
array3 = Array.from(tempSet);

//show output
document.body.querySelector("div").innerHTML = JSON.stringify(array3);
<div style="width:100%;height:4rem;line-height:4rem;background-color:steelblue;color:#DDD;text-align:center;font-family:Calibri" > 
  temp text 
</div>

6
Karan Singla
Array.prototype.add = function(b){
    var a = this.concat();                // clone current object
    if(!b.Push || !b.length) return a;    // if b is not an array, or empty, then return a unchanged
    if(!a.length) return b.concat();      // if original is empty, return b

    // go through all the elements of b
    for(var i = 0; i < b.length; i++){
        // if b's value is not in a, then add it
        if(a.indexOf(b[i]) == -1) a.Push(b[i]);
    }
    return a;
}

// Example:
console.log([1,2,3].add([3, 4, 5])); // will output [1, 2, 3, 4, 5]
5
Lajos Meszaros
array1.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)

これに関して良いことはパフォーマンスです、そして一般的に、あなたがその配列を扱うとき、filter、mapなどのような方法を連鎖しているので、あなたはその行を加えることができます。 1つ(あなたが持っていないメソッドをチェーニングしているとき)、例: 

someSource()
.reduce(...)
.filter(...)
.map(...) 
// and now you want to concat array2 and deduplicate:
.concat(array2).filter((value, pos, arr)=>arr.indexOf(value)===pos)
// and keep chaining stuff
.map(...)
.find(...)
// etc

(私はArray.prototypeを汚染するのは好きではないし、それがチェーンを尊重する唯一の方法になるだろう - 新しい関数を定義することはそれを壊すだろう - だから私はこれを達成する唯一の方法がこのようなものだと思う

5
cancerbero

新しい解決策(これはArray.prototype.indexOfArray.prototype.concatを使います):

Array.prototype.uniqueMerge = function( a ) {
    for ( var nonDuplicates = [], i = 0, l = a.length; i<l; ++i ) {
        if ( this.indexOf( a[i] ) === -1 ) {
            nonDuplicates.Push( a[i] );
        }
    }
    return this.concat( nonDuplicates )
};

使用法:

>>> ['Vijendra', 'Singh'].uniqueMerge(['Singh', 'Shakya'])
["Vijendra", "Singh", "Shakya"]

Array.prototype.indexOf(Internet Explorer用):

Array.prototype.indexOf = Array.prototype.indexOf || function(elt)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from): Math.floor(from); 
    if (from < 0)from += len;

    for (; from < len; from++)
    {
      if (from in this && this[from] === elt)return from;
    }
    return -1;
  };
5
meder omuraliev

ES6の場合は、1行だけです。

a = [1, 2, 3, 4]
b = [4, 5]
[...new Set(a.concat(b))]  // [1, 2, 3, 4, 5]
4
user1079877
var arr1 = [1, 3, 5, 6];
var arr2 = [3, 6, 10, 11, 12];
arr1.concat(arr2.filter(ele => !arr1.includes(ele)));
console.log(arr1);

output :- [1, 3, 5, 6, 10, 11, 12]
3
Bharti Ladumor

それのために...これは単一行の解決策です:

const x = [...new Set([['C', 'B'],['B', 'A']].reduce( (a, e) => a.concat(e), []))].sort()
// ['A', 'B', 'C']

特に読みやすくはありませんが、誰かに役立つ可能性があります。

  1. 初期アキュムレータ値を空の配列に設定してreduce関数を適用します。
  2. Reduce関数はconcatを使って各サブ配列をアキュムレータ配列に追加します。
  3. この結果は、新しいSetを作成するためのコンストラクタパラメータとして渡されます。
  4. 拡散演算子はSetを配列に変換するために使用されます。
  5. sort()関数は新しい配列に適用されます。
3
Mark Tyers

ES2015による機能的アプローチ

機能的なアプローチに従うと、2つのunionname__sのArrayname__は、単にconcatname__とfiltername__の合成です。最適なパフォーマンスを提供するために、プロパティ検索に最適化されたネイティブのSetname__データ型を使用します。

とにかく、unionname__関数と関連した重要な質問は、どのように重複を扱うかです。以下の並べ替えが可能です。

Array A      + Array B

[unique]     + [unique]
[duplicated] + [unique]
[unique]     + [duplicated]
[duplicated] + [duplicated]

最初の2つの置換は、単一の関数で簡単に処理できます。ただし、最後の2つは、Setname__検索に依存している限り処理できないため、より複雑です。普通の古いObjectname__プロパティ検索への切り替えは深刻なパフォーマンスヒットを伴うことになるので、以下の実装では3番目と4番目の置換を無視しています。あなたはそれらをサポートするためにunionname__の別のバージョンを構築しなければならないでしょう。


// small, reusable auxiliary functions

const comp = f => g => x => f(g(x));
const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const afrom = apply(Array.from);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// de-duplication

const dedupe = comp(afrom) (createSet);


// the actual union function

const union = xs => ys => {
  const zs = createSet(xs);  
  return concat(xs) (
    filter(x => zs.has(x)
     ? false
     : zs.add(x)
  ) (ys));
}


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];


// here we go

console.log( "unique/unique", union(dedupe(xs)) (ys) );
console.log( "duplicated/unique", union(xs) (ys) );

これ以降は、任意の数の配列を受け入れるunionnname__関数を実装するのは簡単です(naomikのコメントにヒントを得て)。

// small, reusable auxiliary functions

const uncurry = f => (a, b) => f(a) (b);
const foldl = f => acc => xs => xs.reduce(uncurry(f), acc);

const apply = f => a => f(a);
const flip = f => b => a => f(a) (b);
const concat = xs => y => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));


// union and unionn

const union = xs => ys => {
  const zs = createSet(xs);  
  return concat(xs) (
    filter(x => zs.has(x)
     ? false
     : zs.add(x)
  ) (ys));
}

const unionn = (head, ...tail) => foldl(union) (head) (tail);


// mock data

const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,4,5,6,6];
const zs = [0,1,2,3,4,5,6,7,8,9];


// here we go

console.log( unionn(xs, ys, zs) );

unionnname__は単なるfoldlname__(別名Array.prototype.reduce)です。これはunionname__をそのリデューサーとして取ります。注:実装は追加のアキュムレータを使用しないため、引数なしで適用するとエラーをスローします。

2
user6445533

これを行う最も簡単な方法は、concat()を使用して配列をマージしてからfilter()を使用して重複を削除するか、concat()を使用してからマージした配列をSet()の中に入れることです。

最初の方法: 

const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
//now use filter to remove dups
const removeDuplicates = mergedArray.filter((elem, index) =>  mergedArray.indexOf(elem) === index); // [1,2,3, 4]

2番目の方法(ただし、UIにパフォーマンスの影響がある)

const firstArray = [1,2, 2];
const secondArray = [3,4];
// now lets merge them
const mergedArray = firstArray.concat(secondArray); // [1,2,2,3,4]
const removeDuplicates = new Set(mergedArray);
2
Stelios Voskos

Dojo 1.6以降

var unique = []; 
var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = array1.concat(array2); // Merged both arrays

dojo.forEach(array3, function(item) {
    if (dojo.indexOf(unique, item) > -1) return;
    unique.Push(item); 
});

更新

実用的なコードを見てください。

http://jsfiddle.net/UAxJa/1/

2
Richard Ayotte

元の配列が重複排除を必要としないと仮定すると、これはかなり速く、元の順序を保持し、元の配列を変更しないはずです。

function arrayMerge(base, addendum){
    var out = [].concat(base);
    for(var i=0,len=addendum.length;i<len;i++){
        if(base.indexOf(addendum[i])<0){
            out.Push(addendum[i]);
        }
    }
    return out;
}

使用法:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = arrayMerge(array1, array2);

console.log(array3);
//-> [ 'Vijendra', 'Singh', 'Shakya' ]
2
Billy Moon

ES6ベースのユニオンソリューション

let arr1 = [1,2,3,4,5];
let arr2 = [3,4,5,6];
let result = [...new Set([...arr1, ...arr2])];
console.log(result);

2
Vahid Akhtar

無制限の数の配列または非配列をマージして一意にします。

function flatMerge() {
    return Array.prototype.reduce.call(arguments, function (result, current) {
        if (!(current instanceof Array)) {
            if (result.indexOf(current) === -1) {
                result.Push(current);
            }
        } else {
            current.forEach(function (value) {
                console.log(value);
                if (result.indexOf(value) === -1) {
                    result.Push(value);
                }
            });
        }
        return result;
    }, []);
}

flatMerge([1,2,3], 4, 4, [3, 2, 1, 5], [7, 6, 8, 9], 5, [4], 2, [3, 2, 5]);
// [1, 2, 3, 4, 5, 7, 6, 8, 9]

flatMerge([1,2,3], [3, 2, 1, 5], [7, 6, 8, 9]);
// [1, 2, 3, 5, 7, 6, 8, 9]

flatMerge(1, 3, 5, 7);
// [1, 3, 5, 7]
2
TxRegex

受け入れられた答えは私のテストでは最も遅いようです。

note - Key によって2つのオブジェクトの配列をマージします

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<button type='button' onclick='doit()'>do it</button>
<script>
function doit(){
    var items = [];
    var items2 = [];
    var itemskeys = {};
    for(var i = 0; i < 10000; i++){
        items.Push({K:i, C:"123"});
        itemskeys[i] = i;
    }

    for(var i = 9000; i < 11000; i++){
        items2.Push({K:i, C:"123"});
    }

    console.time('merge');
    var res = items.slice(0);

    //method1();
    method0();
    //method2();

    console.log(res.length);
    console.timeEnd('merge');

    function method0(){
        for(var i = 0; i < items2.length; i++){
            var isok = 1;
            var k = items2[i].K;
            if(itemskeys[k] == null){
                itemskeys[i] = res.length;
                res.Push(items2[i]);
            }
        }
    }

    function method1(){
        for(var i = 0; i < items2.length; i++){
            var isok = 1;
            var k = items2[i].K;

            for(var j = 0; j < items.length; j++){
                if(items[j].K == k){
                    isok = 0;
                    break;
                }
            }

            if(isok) res.Push(items2[i]);
        }  
    }

    function method2(){
        res = res.concat(items2);
        for(var i = 0; i < res.length; ++i) {
            for(var j = i+1; j < res.length; ++j) {
                if(res[i].K === res[j].K)
                    res.splice(j--, 1);
            }
        }
    }
}
</script>
</body>
</html>
2
Omu

Filterを使った最も簡単な解決策:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var mergedArrayWithoutDuplicates = array1.concat(
  array2.filter(seccondArrayItem => !array1.includes(seccondArrayItem))
);
2
Jackkobec

単一配列の重複排除または複数配列入力のマージと重複排除。以下の例.

eS6を使用する - のために、

私は複数の配列引数をとるこの単純な関数を書きました。この関数は、重複した値を1つの配列にのみ連結して、後でそれらを削除できるようにすることはしません。

ショートファンクション定義(9行のみ)

/**
* This function merging only arrays unique values. It does not merges arrays in to array with duplicate values at any stage.
*
* @params ...args Function accept multiple array input (merges them to single array with no duplicates)
* it also can be used to filter duplicates in single array
*/
function arrayDeDuplicate(...args){
   let set = new Set(); // init Set object (available as of ES6)
   for(let arr of args){ // for of loops through values
      arr.map((value) => { // map adds each value to Set object
         set.add(value); // set.add method adds only unique values
      });
   }
   return [...set]; // destructuring set object back to array object
   // alternativly we culd use:  return Array.from(set);
}

使用例 _ codepen _

// SCENARIO 
let a = [1,2,3,4,5,6];
let b = [4,5,6,7,8,9,10,10,10];
let c = [43,23,1,2,3];
let d = ['a','b','c','d'];
let e = ['b','c','d','e'];

// USEAGE
let uniqueArrayAll = arrayDeDuplicate(a, b, c, d, e);
let uniqueArraySingle = arrayDeDuplicate(b);

// OUTPUT
console.log(uniqueArrayAll); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 43, 23, "a", "b", "c", "d", "e"]
console.log(uniqueArraySingle); // [4, 5, 6, 7, 8, 9, 10]
2
DevWL

あなたのレビューのためのreduce funcによるもう一つのアプローチ:

function mergeDistinct(arResult, candidate){
  if (-1 == arResult.indexOf(candidate)) {
    arResult.Push(candidate);
  }
  return arResult;
}

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];

var arMerge = [];
arMerge = array1.reduce(mergeDistinct, arMerge);
arMerge = array2.reduce(mergeDistinct, arMerge);//["Vijendra","Singh","Shakya"];
1
Dmitry Ragozin

これは簡単で、jQueryを使って1行で実行できます。

var arr1 = ['Vijendra', 'Singh'], arr2 =['Singh', 'Shakya'];

$.unique(arr1.concat(arr2))//one line

["Vijendra", "Singh", "Shakya"]
1
ucefkh

LiraNunaのセグエとしての1行ソリューション

let array1 = ["Vijendra","Singh"];
let array2 = ["Singh", "Shakya"];

// Merges both arrays
let array3 = array1.concat(array2); 

//REMOVE DUPLICATE
let removeDuplicate = [...new Set(array3)];
console.log(removeDuplicate);
1
Jonca33

これは簡単な例です:

var unique = function(array) {
    var unique = []
    for (var i = 0; i < array.length; i += 1) {
        if (unique.indexOf(array[i]) == -1) {
            unique.Push(array[i])
        }
    }
    return unique
}

var uniqueList = unique(["AAPL", "MSFT"].concat(["MSFT", "BBEP", "GE"]));

冗長な要素を削除するためにunique(array)を定義し、2つの配列を組み合わせるためにconcat関数を使います。

1
Zorayr
var MergeArrays=function(arrayOne, arrayTwo, equalityField) {
    var mergeDictionary = {};

    for (var i = 0; i < arrayOne.length; i++) {
        mergeDictionary[arrayOne[i][equalityField]] = arrayOne[i];
    }

    for (var i = 0; i < arrayTwo.length; i++) {
        mergeDictionary[arrayTwo[i][equalityField]] = arrayTwo[i];
    }

    return $.map(mergeDictionary, function (value, key) { return value });
}

辞書とJqueryを利用すると、2つの配列をマージして重複を避けることができます。私の例では、オブジェクトに与えられたフィールドを使っていますが、オブジェクトそのものでも構いません。 

1
Zach Lewis

Lodashを使う

@ GijsjanBの答えは便利だと思いましたが、私の配列には多くの属性を持つオブジェクトが含まれていたので、属性の1つを使ってそれらを重複排除する必要がありました。

これがlodashを使った私の解決策です

userList1 = [{ id: 1 }, { id: 2 }, { id: 3 }]
userList2 = [{ id: 3 }, { id: 4 }, { id: 5 }]
// id 3 is repeated in both arrays

users = _.unionWith(userList1, userList2, function(a, b){ return a.id == b.id });

// users = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }]

3番目のパラメータとして渡す関数には2つの引数(2つの要素)があり、それらが等しい場合はtrueを返す必要があります。 

1
Felo Vilches

2つの配列をスプレッド演算子で連結する生意気な小さな方法を学びました:

var array1 = ['tom', 'dick', 'harry'];
var array2 = ['martin', 'ricky'];

array1.Push(...array2);

"..."スプレッド演算子は次の配列を個々の項目に分割し、それからPushはそれらを別々の引数として扱うことができます。

1
Lightfooted

これは私の2番目の答えですが、私は最速だと思いますか?誰かに私のことを確認してもらい、コメントに答えてほしいのですが。

私の最初の試みは約99k ops/secを打った、そしてこれが回避するのは390k ops/sec対140kの他の主要なjsperfテストを言っている。

http://jsperf.com/merge-two-arrays-keeping-only-unique-values/26

今回はできるだけアレイの相互作用をできるだけ少なくするようにしましたが、パフォーマンスが向上したように見えました。

function findMerge(a1, a2) {
    var len1 = a1.length;

    for (var x = 0; x < a2.length; x++) {
        var found = false;

        for (var y = 0; y < len1; y++) {
            if (a2[x] === a1[y]) {
                found = true;
                break;
            }
        }

        if(!found){
            a1.Push(a2.splice(x--, 1)[0]);
        }
    }

    return a1;
}

編集:私は私の機能にいくつかの変更を加えました、そしてパフォーマンスはjsperfサイトの他のものと比較して劇的です。

1
David Kirk

特定のプロパティ(IDなど)の重複が不要な場合

let noDuplicate = array1.filter ( i => array2.findIndex(a => i.id==a.id)==-1 );
let result = [...noDuplicate, ...array2];
1
priolo priolus

一意のオブジェクトをチェックしたい場合は、比較にJSON.stringifyを使用してください。 

function arrayUnique(array) {
    var a = array.concat();
    for(var i=0; i<a.length; ++i) {
        for(var j=i+1; j<a.length; ++j) {
            if(JSON.stringify(a[i]) === JSON.stringify(a[j]))
                a.splice(j--, 1);
        }
    }

    return a;
}
1
Jason Matthews

計算時間の観点から、これが最も効果的なものです。また、それは要素の初期の順序を保ちます。

最初に2番目の配列からすべての重複をフィルター処理し、次に最初の配列に残っているものを連結します。

var a = [1,2,3];
var b = [5,4,3];
var c = a.concat(b.filter(function(i){
    return a.indexOf(i) == -1;
}));
console.log(c); // [1, 2, 3, 5, 4]

これは、配列が値を見逃してはいけないという欠点を伴い、少し改良された(より速い)バージョンです。

var i, c = a.slice(), ci = c.length;
for(i = 0; i < b.length; i++){
    if(c.indexOf(b[i]) == -1)
        c[ci++] = b[i];
}
1
AlexTR
Array.prototype.union = function (other_array) {
/* you can include a test to check whether other_array really is an array */
  other_array.forEach(function(v) { if(this.indexOf(v) === -1) {this.Push(v);}}, this);    
}
1
StickyBandit

var array1 = ["one","two"];
var array2 = ["two", "three"];
var collectionOfTwoArrays = [...array1, ...array2];    
var uniqueList = array => [...new Set(array)];
console.log('Collection :');
console.log(collectionOfTwoArrays);    
console.log('Collection without duplicates :');
console.log(uniqueList(collectionOfTwoArrays));

0
Shiva
  • これを実現する最新の方法は、単純に拡散演算子を使用することです。
  • また、重複を避けるために、Setsを効率的に使用できます。 集合はデフォルトで複製を許可しません
  • Setから配列として出力を取得するには、Array.from()を使用します。

だから、これはあなたのシナリオのためのデモンストレーションです -

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
var resArr = Array.from(new Set([...array1, ...array2]));
console.log(resArr);

0
Tushar Walzade

ES2019

union(array1, array2, array3, ...)のように使用できます

/**
 * Merges two or more arrays keeping unique items. This method does
 * not change the existing arrays, but instead returns a new array.
 */
function union<T>(...arrays: T[]) {
  return [...new Set([...arrays].flat())];
}

flat()関数のためにES2019ですが、 core-js を使用してポリフィルとして取得できます。ここのTはTypeScriptジェネリック型であり、TypeScriptを使用していない場合は削除できます。 TypeScriptを使用している場合は、"lib": ["es2019.array"]のコンパイラオプションにtsconfig.jsonを追加してください。

または...

lodashを使用するだけ _。union

0
orad

モジュラー、一般

これは、2つの重要な機能を組み合わせることによって達成できます。

const getUniqueMerge = (...arrs) => getUniqueArr(mergeArrs(...arrs))
const getUniqueArr = (array) => Array.from(new Set(array))  
const mergeArrs = (...arrs) => [].concat(...arrs)

無制限の配列や値を扱うことができます

console.log(getUniqueMerge(["Vijendra","Singh"],["Singh", "Shakya"])
// ["Vijendra", "Singh", "Shakya"]

console.log(getUniqueMerge(["Sheldon", "Cooper"], ["and", "Cooper", "Amy", "and"], "Farrah", "Amy", "Fowler"))
// ["Sheldon", "Cooper", "and", "Amy", "Farrah", "Fowler"]
0
Ben Carp

私はこれがより速く働くと思います。

removeDup = a => {

for (let i = a.length - 1; i >= 0; i--) {
    for (let j = i-1; j >= 0; j--) {
        if (a[i] === a[j])
            a.splice(j--, 1);
    }
}

return a;

}

0
Muhammad

私のように、あなたがより古いブラウザをサポートする必要があるならば、これはIE6 +で動作します

function es3Merge(a, b) {
    var hash = {},
        i = (a = a.slice(0)).length,
        e;

    while (i--) {
        hash[a[i]] = 1;
    }

    for (i = 0; i < b.length; i++) {
        hash[e = b[i]] || a.Push(e);
    }

    return a;
};

http://jsperf.com/merge-two-arrays-keeping-only-unique-values/22

0
Stephen S

これが私の解決策であり、{ https://Gist.github.com/4692150 } _であり、結果が等しく、使いやすい結果です。

function merge_arrays(arr1,arr2)
{
   ... 
   return {first:firstPart,common:commonString,second:secondPart,full:finalString}; 
}

console.log(merge_arrays(
[
[1,"10:55"] ,
[2,"10:55"] ,
[3,"10:55"]
],[
[3,"10:55"] ,
[4,"10:55"] ,
[5,"10:55"]
]).second);

result:
[
[4,"10:55"] ,
[5,"10:55"]
]
0
Shimon Doodkin

これを試すことができます:

const union = (a, b) => Array.from(new Set([...a, ...b]));

console.log(union(["neymar","messi"], ["ronaldo","neymar"]));

0
mitesh7172
Array.prototype.pushUnique = function(values)
{
    for (var i=0; i < values.length; i++)
        if (this.indexOf(values[i]) == -1)
            this.Push(values[i]);
};

試してください:

var array1 = ["Vijendra","Singh"];
var array2 = ["Singh", "Shakya"];
array1.pushUnique(array2);
alert(array1.toString());  // Output: Vijendra,Singh,Shakya
0
StanE

使用法: https://Gist.github.com/samad-aghaei/7250ffb74ed80732debb1cbb14d2bfb0

var _uniqueMerge = function(opts, _ref){
    for(var key in _ref)
        if (_ref && _ref[key] && _ref[key].constructor && _ref[key].constructor === Object)
          _ref[key] = _uniqueMerge((opts ? opts[key] : null), _ref[key] );
        else if(opts && opts.hasOwnProperty(key))
          _ref[key] = opts[key];
        else _ref[key] = _ref[key][1];
    return _ref;
}
0
Samad Aghaei

あなたが純粋にunderscore.jsを使っているのであれば、それはunionWith、unionByを持っていません。

試してみることができます: _.uniq(_.union(arr1, arr2), (obj) => obj.key) (keyは各オブジェクトのキー・パラメーターです)これは、両方の配列の結合後に一意になるのに役立ちます。

0
Vivek Parekh

同じ理由で前に書いただけです(どんな量の配列でも動作します)。

/**
 * Returns with the union of the given arrays.
 *
 * @param Any amount of arrays to be united.
 * @returns {array} The union array.
 */
function uniteArrays()
{
    var union = [];
    for (var argumentIndex = 0; argumentIndex < arguments.length; argumentIndex++)
    {
        eachArgument = arguments[argumentIndex];
        if (typeof eachArgument !== 'array')
        {
            eachArray = eachArgument;
            for (var index = 0; index < eachArray.length; index++)
            {
                eachValue = eachArray[index];
                if (arrayHasValue(union, eachValue) == false)
                union.Push(eachValue);
            }
        }
    }

    return union;
}    

function arrayHasValue(array, value)
{ return array.indexOf(value) != -1; }
0
Geri

そのための最も簡単で簡単な方法は、配列にオブジェクトの要素が含まれているかどうかを示すtrueまたはfalseを返すJavaScriptの関数 "some()"を使用することです。あなたはこれを作ることができます:

var array1 = ["Vijendra","Singh"]; 
var array2 = ["Singh", "Shakya"];

var array3 = array1;

array2.forEach(function(elementArray2){
    var isEquals = array1.some(function(elementArray1){
        return elementArray1 === elementArray2;
    })
    if(!isEquals){
        array3.Push(elementArray2);
    }
});
console.log(array3);

結果: 

["Vijendra", "Singh", "Shakya"]

あなたが望むss ...それを複製せずに...

0
Thiago Araújo