Frage Wie man zwei Arrays in JavaScript zusammenführt und Elemente dupliziert


Ich habe zwei JavaScript-Arrays:

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

Ich möchte, dass die Ausgabe wie folgt aussieht:

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

Das Ausgabe-Array sollte Wörter entfernt haben.

Wie füge ich zwei Arrays in JavaScript zusammen, so dass ich nur die eindeutigen Elemente von jedem Array in der Reihenfolge bekomme, in der sie in die ursprünglichen Arrays eingefügt wurden?


976
2017-10-18 08:34


Ursprung


Antworten:


Einfaches Zusammenführen der Arrays (ohne Duplikate zu entfernen)

ES5-Version verwenden 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 Destrukturierung

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

Da es keine "eingebaute" Möglichkeit gibt, Duplikate zu entfernen (ECMA-262 hat eigentlich Array.forEach was wäre toll dafür), wir müssen es manuell machen:

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, um es zu benutzen:

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

Dies wird auch die Reihenfolge der Arrays beibehalten (d. H. Keine Sortierung benötigt).

Da ärgern sich viele Leute über die Prototypenerweiterung von Array.prototype und for in Schleifen, hier ist eine weniger invasive Art, sie zu benutzen:

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, in denen ES5 verfügbar ist, können Sie verwenden Object.defineProperty so was:

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

1233
2017-10-18 08:42



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


510
2018-05-08 13:24



Zuerst verketten Sie die beiden Arrays, anschließend filtern Sie nur die eindeutigen Elemente aus.

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, die eindeutigen Elemente herauszufiltern b vor der Verkettung mit 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]

193
2018-04-15 10:08



Dies ist eine ECMAScript 6-Lösung mit Spread-Operator und Array-Generika.

Derzeit funktioniert es nur mit Firefox und möglicherweise Internet Explorer Technical Preview.

Aber wenn du es benutzt BabelDu kannst 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))];
}

119
2017-12-27 06:28



ES6

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

ODER

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

ODER

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

86
2017-08-14 08:08



Hier ist ein etwas anderer Blick auf die Schleife. Mit einigen der Optimierungen in der neuesten Version von Chrome ist es die schnellste Methode zum Lö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: ~ 589 k Ops / s
Filter: ~ 445k Ops / s
lodash: 308k ops / s
für Schleifen: 225 k Ops / s

Ein Kommentar wies darauf hin, dass eine meiner Setup-Variablen dazu führte, dass meine Schleife dem Rest vorausging, weil sie kein leeres Array initialisieren musste, um darauf zu schreiben. Ich stimme dem zu, also habe ich den Test sogar auf das Spielfeld umgeschrieben und eine noch schnellere Option hinzugefügt.

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

var whileLoopAlt = function(array1, array2) {
    var array3 = [];
    var arr = array1.concat(array2);
    var len = arr.length;
    var assoc = {};

    while(len--) {
        var itm = arr[len];

        if(!assoc[itm]) { // Eliminate the indexOf call
            array3.unshift(itm);
            assoc[itm] = true;
        }
    }

    return array3;
};

In dieser alternativen Lösung habe ich die assoziative Array-Lösung einer Antwort kombiniert, um die Lösung zu eliminieren .indexOf() Rufen Sie die Schleife auf, die die Dinge mit einer zweiten Schleife verlangsamte, und enthielten einige der anderen Optimierungen, die andere Benutzer in ihren Antworten ebenfalls vorgeschlagen haben.

Die obere Antwort hier mit der doppelten Schleife auf jeden Wert (i-1) ist immer noch deutlich langsamer. lodash macht immer noch stark, und ich würde es immer noch jedem empfehlen, der nichts dagegen hat, seinem Projekt eine Bibliothek hinzuzufügen. Für diejenigen, die nicht wollen, ist meine while-Schleife immer noch eine gute Antwort und die Filter-Antwort hat hier eine sehr starke Präsenz, die bei meinen Tests mit dem neuesten Canary Chrome (44.0.2360) zum Zeitpunkt des Schreibens alles übertroffen hat.

Auschecken Mikes Antwort und Dan Stockers Antwort wenn Sie es schneller machen wollen. Diese sind mit Abstand die schnellsten aller Ergebnisse, nachdem sie fast alle brauchbaren Antworten durchlaufen haben.


30
2017-08-04 14:14



Verwendung einer einstellen (ECMAScript 2015) wird es so einfach sein:

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

27
2018-01-06 19:05



Sie können es einfach mit ECMAScript 6 machen,

var array1 = ["Vijendra", "Singh"];
var array2 = ["Singh", "Shakya"];
var array3 = [...new Set([...array1 ,...array2])];
console.log(array3); // ["Vijendra", "Singh", "Shakya"];
  • Benutze die Spread-Operator zum Verketten des Arrays.
  • Benutzen einstellen zum Erstellen eines eindeutigen Satzes von Elementen.
  • Verwenden Sie den Spread-Operator erneut, um das Set in ein Array zu konvertieren.

26
2018-04-07 07:26



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.


14
2017-08-19 13:34



Einfach meine zwei Cent einwerfen.

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 oft benutze, sie verwendet ein Objekt als Hash-Lookup-Tabelle, um die Duplikatprüfung durchzuführen. Unter der Annahme, dass der Hash-Wert O (1) ist, läuft dies in O (n), wobei n eine Länge + Länge ist. Ich habe ehrlich gesagt keine Ahnung, wie der Browser den Hash durchführt, aber er funktioniert auf vielen tausend Datenpunkten gut.


13
2017-12-12 19:50