web-dev-qa-db-de.com

Wie Sie zwei Arrays in JavaScript zusammenführen und Elemente duplizieren

Ich habe zwei JavaScript-Arrays:

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

Ich möchte die Ausgabe sein:

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

Das Ausgabe-Array sollte wiederholte Wörter entfernt haben.

Wie füge ich zwei Arrays in JavaScript zusammen, sodass nur die eindeutigen Elemente aus jedem Array in derselben Reihenfolge angezeigt werden, in der sie in die ursprünglichen Arrays eingefügt wurden?

1090
Vijjendra

Zusammenführen der Arrays (ohne Duplikate zu entfernen)

Verwendung der ES5-Version Array.concat:

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

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

ES6-Version verwenden destructuring

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

Da es keine integrierte Methode zum Entfernen von Duplikaten gibt ( ECMA-262 hat tatsächlich Array.forEach, was dafür gut geeignet wäre), müssen wir dies manuell tun:

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;
};

Dann verwenden Sie es:

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

Dadurch wird auch die Reihenfolge der Arrays beibehalten (d. H. Keine Sortierung erforderlich).

Da sich viele Leute über die Prototyp-Erweiterung von Array.prototype- und for in-Schleifen geärgert haben, können Sie sie hier auf weniger invasive Weise verwenden:

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));

Für diejenigen, die das Glück haben, mit Browsern zu arbeiten, für die ES5 verfügbar ist, können Sie Object.defineProperty wie folgt verwenden:

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

Mit Underscore.js oder Lo-Dash können Sie Folgendes tun:

_.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

Verketten Sie zuerst die beiden Arrays, und filtern Sie anschließend nur die eindeutigen Elemente.

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/

Bearbeiten

Wie von @Dmitry vorgeschlagen (siehe den zweiten Kommentar unten), wäre eine leistungsfähigere Lösung das Herausfiltern der eindeutigen Elemente in b, bevor sie mit a verkettet werden.

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

Dies ist eine ECMAScript 6-Lösung, die spread Operator Array-Generics verwendet.

Derzeit funktioniert es nur mit Firefox und möglicherweise mit der technischen Vorschau von Internet Explorer.

Wenn Sie jedoch Babel verwenden, können Sie es jetzt haben.

// 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

Mit einem Set (ECMAScript 2015) wird es so einfach:

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

Hier ist eine etwas andere Einstellung der Schleife. Mit einigen Optimierungen in der neuesten Version von Chrome ist dies die schnellste Methode zum Auflösen der Vereinigung der beiden Arrays (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-Schleife: ~ 589k ops/s 
filter: ~ 445k ops/s 
lodash: 308k ops/s 
für Schleifen: 225k ops/s

In einem Kommentar wurde darauf hingewiesen, dass eine meiner Setup-Variablen dazu führte, dass meine Schleife vor den Rest verschoben wurde, da sie kein leeres Array zum Schreiben schreiben musste. Ich stimme dem zu, also habe ich den Test sogar ins Spielfeld umgeschrieben und eine noch schnellere Option hinzugefügt.

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;
};

In dieser alternativen Lösung habe ich die assoziative Array-Lösung einer Antwort kombiniert, um den Aufruf .indexOf() in der Schleife zu eliminieren, der die Dinge mit einer zweiten Schleife stark verlangsamte, und einige andere Optimierungen, die andere Benutzer in ihren Antworten vorgeschlagen haben Gut.

Die beste Antwort hier mit der Doppelschleife bei jedem Wert (i-1) ist immer noch wesentlich langsamer. lodash ist immer noch stark, und ich würde es jedem empfehlen, der nichts dagegen hat, eine Bibliothek zu seinem Projekt hinzuzufügen. Für diejenigen, die es nicht wollen, ist meine While-Schleife immer noch eine gute Antwort, und die Filterantwort zeigt hier sehr starke Ergebnisse. Alle meine Tests wurden mit dem neuesten Canary Chrome (44.0.2360) zu diesem Zeitpunkt übertroffen.

Check out Mikes Antwort und Dan Stockers Antwort wenn Sie es schneller machen wollen. Dies sind bei weitem die schnellsten Ergebnisse, nachdem sie fast alle möglichen Antworten durchlaufen haben.

33
slickplaid

Sie können dies einfach mit ECMAScript 6 tun,

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
  • Verwenden Sie den Operator spread , um das Array zu verketten.
  • Verwenden Sie Set , um verschiedene Elemente zu erstellen.
  • Verwenden Sie erneut den Spread-Operator, um das Set in ein Array zu konvertieren.
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;
};

Eine viel bessere Array-Merge-Funktion. 

16
GAgnew

fügen Sie zwei Arrays zusammen und entfernen Sie Duplikate in 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

Vermeiden Sie einfach verschachtelte Schleifen (O (n ^ 2)) und .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

Ich habe nur meine zwei Cents eingeworfen.

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;
}

Dies ist eine Methode, die ich häufig verwende. Sie verwendet ein Objekt als hashlookup-Tabelle, um die doppelte Überprüfung durchzuführen. Angenommen, der Hash ist O (1), dann läuft dieser in O(n), wobei n a.length + b.length ist. Ich habe ehrlich gesagt keine Ahnung, wie der Browser den Hash ausführt, aber er ist bei vielen Tausenden von Datenpunkten gut.

14
Mike

Warum benutzt du keinen Gegenstand? Es sieht so aus, als würden Sie versuchen, ein Set zu modellieren. Dies wird die Reihenfolge jedoch nicht beibehalten.

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

Mein eineinhalb Cent:

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

Die beste Lösung...

Sie können direkt in der Browserkonsole nachsehen, indem Sie auf ... drücken.

Ohne zu duplizieren

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

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

Mit Duplikat

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

Wenn Sie ohne Duplikat wollen, können Sie von hier aus eine bessere Lösung ausprobieren - Shouting Code .

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

Versuchen Sie es mit der Chrome-Browserkonsole

 f12 > console

Ausgabe:

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

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

Simplified simos Antwort und machte daraus eine Nice-Funktion.

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

Sie können es einfach erreichen, indem Sie Underscore.js => uniq verwenden:

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

console.log(array3)

Es wird gedruckt ["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
  }

Die Implementierung der indexOf-Methode für andere Browser stammt aus MDC

6
Amarghosh

Es kann mit Set gemacht werden.

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)

Das Schöne an diesem ist die Leistung, und wenn Sie im Allgemeinen mit Arrays arbeiten, gibt es Verkettungsmethoden wie Filter, Map usw., so dass Sie diese Zeile hinzufügen können und Array2 mit array1 zusammenfügen und deduplizieren wird, ohne dass ein Verweis auf die spätere benötigt wird eine (wenn Sie Methoden ketten, die Sie nicht haben), Beispiel: 

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

(Ich mag es nicht, Array.prototype zu verschmutzen, und das wäre der einzige Weg, die Kette zu respektieren - das Definieren einer neuen Funktion bricht sie - also denke ich, dass so etwas der einzige Weg ist, das zu erreichen.)

5
cancerbero

Neue Lösung (die Array.prototype.indexOf und Array.prototype.concat verwendet):

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 )
};

Verwendungszweck:

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

Array.prototype.indexOf (für 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

Für ES6 nur eine Zeile:

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

um das zu erreichen ... hier ist eine einzeilige Lösung:

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

Nicht besonders lesbar, aber es kann jemandem helfen:

  1. Wendet eine Verringerungsfunktion an, wobei der anfängliche Akkumulatorwert auf ein leeres Array gesetzt ist.
  2. Die Reduzierungsfunktion verwendet concat, um jedes Subarray an das Akkumulatorarray anzuhängen.
  3. Das Ergebnis wird als Konstruktorparameter übergeben, um eine neue Set zu erstellen.
  4. Der Spread-Operator wird verwendet, um die Variable Set in ein Array umzuwandeln.
  5. Die Funktion sort() wird auf das neue Array angewendet.
3
Mark Tyers

Ein funktionaler Ansatz mit ES2015

Dem funktionalen Ansatz folgend ist eine union von zwei Arrays nur die Zusammensetzung von concat und filter. Um eine optimale Leistung zu erzielen, greifen wir auf den nativen Datentyp Set zurück, der für die Suche nach Eigenschaften optimiert ist.

Auf jeden Fall ist die Schlüsselfrage in Verbindung mit einer union-Funktion, wie Duplikate behandelt werden sollen. Folgende Permutationen sind möglich:

Array A      + Array B

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

Die ersten beiden Permutationen sind mit einer einzigen Funktion leicht zu handhaben. Die letzten beiden sind jedoch komplizierter, da Sie sie nicht verarbeiten können, solange Sie sich auf Set-Lookups verlassen. Da das Wechseln zu einfachen alten Object-Eigenschaftensuchen einen ernsthaften Performance-Treffer nach sich ziehen würde, ignoriert die folgende Implementierung die dritte und vierte Permutation. Sie müssten eine eigene Version von union erstellen, um sie zu unterstützen.


// 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) );

Von nun an wird es trivial, eine unionn-Funktion zu implementieren, die eine beliebige Anzahl von Arrays akzeptiert (inspiriert von naomiks Kommentaren):

// 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) );

Es stellt sich heraus, dass unionn nur foldl (aka Array.prototype.reduce) ist, was union als Reduzierer nimmt. Hinweis: Da die Implementierung keinen zusätzlichen Akkumulator verwendet, wird ein Fehler ausgegeben, wenn Sie diesen ohne Argumente anwenden.

2
user6445533

Der einfachste Weg, dies zu tun, besteht entweder darin, die Arrays mit concat() zusammenzuführen und dann mit filter() die Duplikate zu entfernen, oder concat() zu verwenden und dann das zusammengeführte Array in eine Set() zu setzen.

Erster Weg: 

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]

Zweiter Weg (aber mit Auswirkungen auf die Benutzeroberfläche):

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

Im 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); 
});

Update

Siehe Arbeitscode.

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

2
Richard Ayotte

Angenommen, die ursprünglichen Arrays benötigen keine Deduplizierung, dies sollte ziemlich schnell sein, die ursprüngliche Reihenfolge beibehalten und die ursprünglichen Arrays nicht ändern.

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;
}

verwendungszweck:

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

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

ES6-basierte Gewerkschaftslösung

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

Fügen Sie eine unbegrenzte Anzahl von Arrays oder Nicht-Arrays zusammen und halten Sie sie eindeutig:

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

sieht aus wie die akzeptierte Antwort in meinen Tests die langsamste ist;

note Ich füge 2 Arrays von Objekten zusammen mit Key

<!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

Die einfachste Lösung mit Filter:

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

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

DeDuplicate einzelne oder Merge und DeDuplicate mehrere Array-Eingänge. Beispiel unten.

mit ES6 - für destructuring setzen

Ich habe diese einfache Funktion geschrieben, die mehrere Array-Argumente akzeptiert . Hat ziemlich genau das Gleiche wie die darüber liegende Lösung, hat nur mehr praktischen Anwendungsfall. Diese Funktion verkettet doppelte Werte nicht nur in einem Array, sodass sie zu einem späteren Zeitpunkt gelöscht werden können.

KURZFUNKTION DEFINITION (nur 9 Zeilen)

/**
* 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);
}

USE example 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

Ein weiterer Ansatz für Ihre Überprüfung mit reduzierten Funktionen:

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

Dies ist einfach und kann mit jQuery in einer Zeile erfolgen:

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

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

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

Einzeilige Lösung als Übergang zu LiraNuna:

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

Hier ist ein einfaches Beispiel:

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"]));

Wir definieren unique(array), um redundante Elemente zu entfernen und verwenden die concat-Funktion, um zwei Arrays zu kombinieren.

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 });
}

Durch die Verwendung von Wörterbüchern und Jquery können Sie die beiden Arrays zusammenführen und keine Duplikate erhalten. In meinem Beispiel verwende ich ein bestimmtes Feld für das Objekt, könnte aber nur das Objekt selbst sein. 

1
Zach Lewis

Lodash verwenden

Ich fand die Antwort von @ GijsjanB nützlich, aber meine Arrays enthielten Objekte mit vielen Attributen. Daher musste ich sie mithilfe eines der Attribute dekomprimieren.

Hier ist meine Lösung mit 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 }]

Die Funktion, die Sie als dritter Parameter übergeben, hat zwei Argumente (zwei Elemente) und muss true zurückgeben, wenn sie gleich sind. 

1
Felo Vilches

Ich habe eine freche kleine Möglichkeit gelernt, zwei Arrays mit dem Spread-Operator zu verketten:

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

array1.Push(...array2);

Der Spread-Operator "..." teilt das folgende Array in einzelne Elemente auf, und Push kann sie als separate Argumente behandeln.

1
Lightfooted

Dies ist meine zweite Antwort, aber ich glaube am schnellsten? Ich möchte, dass jemand nach mir sucht und in den Kommentaren antwortet.

Mein erster Versuch erreichte etwa 99.000 Ops/Sek. Dies bedeutet, dass 390.000 Ops/Sek gegen den anderen führenden Jsperf-Test von 140.000 (für mich) liegen.

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

Ich habe versucht, so viele Array-Interaktionen wie möglich zu minimieren, und es sah so aus, als hätte ich etwas Leistung gebracht.

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;
}

Edit: Ich habe einige Änderungen an meiner Funktion vorgenommen und die Leistung ist im Vergleich zu anderen auf der jsperf-Site drastisch.

1
David Kirk

Wenn Sie keine Duplikate einer bestimmten Eigenschaft wünschen (zum Beispiel die ID)

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

Wenn Sie nach eindeutigen Objekten suchen möchten, verwenden Sie JSON.stringify in Ihrem Vergleich. 

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

Hier geht es um die effektivste, was die Rechenzeit angeht. Es behält auch die ursprüngliche Reihenfolge der Elemente bei.

Filtern Sie zunächst alle Duplikate aus dem zweiten Array, und verketten Sie dann, was noch übrig ist.

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]

Hier ist eine etwas verbesserte (schnellere) Version davon, mit einem Nachteil, dass Arrays keine Werte übersehen dürfen:

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
  • Ein moderner Weg, dies zu erreichen, ist die Verwendung des spread operator.
  • Und um Doppelarbeit zu vermeiden, können wir Sets; Sets erlauben standardmäßig keine Duplikate.
  • Um die Ausgabe eines Arrays aus einem Set zurückzuholen, können Sie Array.from () verwenden.

Hier ist eine Demonstration für Ihr Szenario - 

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

0
Tushar Walzade

ES2019

Sie können es wie union(array1, array2, array3, ...) verwenden.

/**
 * 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())];
}

Es ist ES2019 wegen der Funktion flat(), aber Sie können core-js verwenden, um es als Polyfill zu erhalten. Das T ist hier ein generischer TypeScript-Typ, den Sie entfernen können, wenn Sie TypeScript nicht verwenden. Wenn Sie TypeScript verwenden, müssen Sie "lib": ["es2019.array"] zu den Compileroptionen in tsconfig.json hinzufügen.

oder...

benutze einfach lodash _. union

0
orad

Modular, Allgemein

Dies könnte erreicht werden, indem zwei wesentliche Funktionen zusammengesetzt werden.

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

Es kann eine unbegrenzte Anzahl von Arrays oder Werten verarbeiten

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

Ich denke das geht schneller.

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

Wenn Sie, wie ich, ältere Browser unterstützen müssen, funktioniert dies mit 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

Hier ist meine Lösung https://Gist.github.com/4692150 mit tiefen Gleichnissen und einfach zu verwendendem Ergebnis:

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

Sie können dies versuchen:

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]);
};

Versuchen:

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

Verwendung: 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

Wenn Sie Underscore.js verwenden, gibt es keine unionWith, unionBy

sie können es ausprobieren: _.uniq(_.union(arr1, arr2), (obj) => obj.key) (Schlüssel ist der Schlüsselparameter jedes Objekts) Dies sollte dazu beitragen, nach der Vereinigung beider Arrays eindeutig zu werden.

0
Vivek Parekh

Gerade aus dem gleichen Grund geschrieben (funktioniert mit beliebig vielen Arrays):

/**
 * 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

Der beste und einfachste Weg ist, die Funktion "some ()" von JavaScript zu verwenden, die true oder false zurückgibt und angibt, ob das Array das Element des Objekts enthält. Sie können dies machen:

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);

Die Ergebnisse: 

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

ss du willst ... ohne es zu kopieren ...

0
Thiago Araújo