Cómo fusionar dos matrices en JavaScript y eliminar elementos duplicados

Resuelto Vijjendra asked hace 15 años • 91 respuestas

Tengo dos matrices de JavaScript:

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

Quiero que la salida sea:

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

La matriz de salida debería tener eliminadas las palabras repetidas.

¿Cómo fusiono dos matrices en JavaScript para obtener solo los elementos únicos de cada matriz en el mismo orden en que se insertaron en las matrices originales?

Vijjendra avatar Oct 18 '09 15:10 Vijjendra
Aceptado

Para simplemente fusionar las matrices (sin eliminar duplicados)

Uso de la versión ES5 Array.concat:

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

array1 = array1.concat(array2);

console.log(array1);
Expandir fragmento

actualización 2023

La respuesta original fue de hace años. ES6 es totalmente compatible y IE finalmente está muerto. Esta es la forma más sencilla de fusionar matrices primitivas y de objetos:

const merge = (a, b, predicate = (a, b) => a === b) => {
    const c = [...a]; // copy to avoid side effects
    // add all items from B to copy C if they're not already present
    b.forEach((bItem) => (c.some((cItem) => predicate(bItem, cItem)) ? null : c.push(bItem)))
    return c;
}

merge(['a', 'b', 'c'], ['c', 'x', 'd']);
// => ['a', 'b', 'c', 'x', 'd']

merge([{id: 1}, {id: 2}], [{id: 2}, {id: 3}], (a, b) => a.id === b.id);
// [{id: 1}, {id: 2}, {id: 3}]

Respuesta original

La versión ES6 utiliza la desestructuración

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

Dado que no existe una forma "integrada" de eliminar duplicados ( ECMA-262 en realidad tiene Array.forEachlo que sería excelente para esto), tenemos que hacerlo manualmente. Tenga en cuenta que esto contamina el Arrayprototipo, utilícelo con precaución.

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

Entonces, para usarlo:

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

Esto también preservará el orden de las matrices (es decir, no es necesario ordenarlas).

Dado que a muchas personas les molesta el aumento de prototipos de bucles Array.prototypey for in, aquí hay una forma menos invasiva de usarlo:

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

Para aquellos que tienen la suerte de trabajar con navegadores donde está disponible ES5, pueden usarlo Object.definePropertyasí:

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;
    }
});
LiraNuna avatar Oct 18 '2009 08:10 LiraNuna

Con Underscore.js o Lo-Dash puedes hacer:

console.log(_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>
Expandir fragmento

http://underscorejs.org/#union

http://lodash.com/docs#union

GijsjanB avatar May 08 '2012 13:05 GijsjanB
[...array1,...array2] //   =>  don't remove duplication 

O

[...new Set([...array1 ,...array2])]; //   => remove duplication
Abdennour TOUMI avatar Aug 14 '2016 08:08 Abdennour TOUMI

Primero concatene las dos matrices, luego filtre solo los elementos únicos:

var a = [1, 2, 3], b = [101, 2, 1, 10]
var c = a.concat(b)
var d = c.filter((item, pos) => c.indexOf(item) === pos)

console.log(d) // d is [1, 2, 3, 101, 10]
Expandir fragmento

Editar

Como se sugirió, una solución más inteligente en términos de rendimiento sería filtrar los elementos únicos bantes de concatenar con a:

var a = [1, 2, 3], b = [101, 2, 1, 10]
var c = a.concat(b.filter((item) => a.indexOf(item) < 0))

console.log(c) // c is [1, 2, 3, 101, 10]
Expandir fragmento

simo avatar Apr 15 '2014 10:04 simo

Esta es una solución ECMAScript 6 que utiliza operadores de extensión y genéricos de matriz.

Actualmente sólo funciona con Firefox y posiblemente con Internet Explorer Technical Preview.

Pero si usas Babel , puedes tenerlo ahora.

const input = [
  [1, 2, 3],
  [101, 2, 1, 10],
  [2, 1]
];
const mergeDedupe = (arr) => {
  return [...new Set([].concat(...arr))];
}

console.log('output', mergeDedupe(input));
Expandir fragmento

Adria avatar Dec 27 '2014 06:12 Adria