Fusionar 2 matrices de objetos

112

Echemos un vistazo a un ejemplo.

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

Necesito fusionar esas 2 matrices de objetos y crear la siguiente matriz:

arr3 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'});

¿Hay alguna función de JavaScript o jQuery para hacer esto?

$.extendno me queda bien. Vuelve

arr4 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
Alejandro
fuente
15
¿Qué pasó con {name: "lang", value: "English"}?
Shadow Wizard es Ear For You
Lo siento. Menciono $ .extend, no $ .merge.
Alexander
1
Quiero decir, ¿cuál es la lógica involucrada? ¿Cómo quieres fusionar las matrices? No está claro a partir de sus ejemplos.
Shadow Wizard es Ear For You
Muchas gracias a todos. Lo hice manualmente.
Alexander
6
@ShadowWizard, creo que lo que significó el OP fue actualizar si existe y presionar si no.
Amin Mohamed Ajani

Respuestas:

84

Si desea fusionar 2 matrices de objetos en JavaScript. Puedes usar este truco de una línea

Array.prototype.push.apply(arr1,arr2);

Por ejemplo

var arr1 = [{name: "lang", value: "English"},{name: "age", value: "18"}];
var arr2 = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

Array.prototype.push.apply(arr1,arr2); 

console.log(arr1);  // final merged result will be in arr1

Salida:

[{"name":"lang","value":"English"},
{"name":"age","value":"18"},
{"name":"childs","value":"5"},
{"name":"lang","value":"German"}]
Jahanzaib Aslam
fuente
Hasta ahora, este es el uso más simple y funciona bien. Gracias por compartirlo.
Leo Caseiro
17
mismo resultado que el mucho más simple:arr1 = arr1.concat(arr2)
keithpjolley
7
pero esto no es fusionar!
Dimitri Kopriwa
1
Los resultados no son los mismos. concatdevolverá una nueva matriz y romperá cualquier referencia que tenga.
Bpainter
8
Esto no responde a la pregunta, la matriz resultante debe tener 3 objetos, no 4. Cambió los valores de muestra. Básicamente, lo que OP quiere es fusionar dos matrices de objetos y eliminar valores duplicados.
Ranjan
43

Con ES6 puede hacerlo muy fácil como se muestra a continuación:

var arr1 = new Array({name: "lang", value: "German"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var arr3 = [...arr1, ...arr2];

Salida:

    arr3 = [
      {"name":"lang","value":"German"},
      {"name":"age","value":"18"},
      {"name":"childs","value":"5"},
      {"name":"lang","value":"German"}
    ]
Nguyễn Bá Vinh
fuente
6
Esta debería ser la mejor respuesta.
nocdib
20
Esto no hace lo que el OP estaba buscando, no debería haber un segundo objeto que contenga{ name: 'lang', value: 'German'}
Will
3
No sé por qué se vota esta respuesta. Lo que @ daveanderson88 quiere es diferente esta respuesta.
Nguyễn Xuân Hoàng
33

Para aquellos que están experimentando con cosas modernas:

var odd = [
    { name : "1", arr: "in odd" },
    { name : "3", arr: "in odd" }
];

var even = [
    { name : "1", arr: "in even" },
    { name : "2", arr: "in even" },
    { name : "4", arr: "in even" }
];

// ----
// ES5 using Array.filter and Array.find
function merge(a, b, prop){
  var reduced = a.filter(function(aitem){
      return ! b.find(function(bitem){
          return aitem[prop] === bitem[prop];
      });
  });
  return reduced.concat(b);
}
console.log( "ES5", merge(odd, even, "name") );

// ----
// ES6 arrow functions
function merge(a, b, prop){
    var reduced =  a.filter( aitem => ! b.find ( bitem => aitem[prop] === bitem[prop]) )
  return reduced.concat(b);
}
console.log( "ES6", merge(odd, even, "name") );

// ----
// ES6 one-liner
var merge = (a, b, p) => a.filter( aa => ! b.find ( bb => aa[p] === bb[p]) ).concat(b);


console.log( "ES6 one-liner", merge(odd, even, "name") );

// Results
// ( stuff in the "b" array replaces things in the "a" array )
// [
//    {
//         "name": "3",
//         "arr": "in odd"
//     },
//     {
//         "name": "1",
//         "arr": "in even"
//     },
//     {
//         "name": "2",
//         "arr": "in even"
//     },
//     {
//         "name": "4",
//         "arr": "in even"
//     }
// ]
Beto
fuente
29

Actualización 12 Oct 2019

Nueva versión basada solo en Javascript más reciente y sin la necesidad de ninguna biblioteca de terceros.

const mergeByProperty = (target, source, prop) => {
  source.forEach(sourceElement => {
    let targetElement = target.find(targetElement => {
      return sourceElement[prop] === targetElement[prop];
    })
    targetElement ? Object.assign(targetElement, sourceElement) : target.push(sourceElement);
  })
}
var target /* arr1 */ = [{name: "lang", value: "English"}, {name: "age", value: "18"}];
var source /* arr2 */ = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

mergeByProperty(target, source, 'name');

console.log(target)

Esta respuesta se estaba volviendo vieja, las bibliotecas como lodash y el subrayado son mucho menos necesarias en estos días. En esta nueva versión, la matriz de destino (arr1) es con la que estamos trabajando y queremos mantener actualizada. La matriz de origen (arr2) es de donde provienen los nuevos datos y queremos que se fusionen en nuestra matriz de destino .

Recorrimos la matriz de origen en busca de nuevos datos, y para cada objeto que aún no se encuentra en nuestra matriz de destino , simplemente agregamos ese objeto usando target.push (sourceElement) Si, según nuestra propiedad clave ('nombre') , un el objeto ya está en nuestra matriz de destino; actualizamos sus propiedades y valores usando Object.assign (targetElement, sourceElement) . Nuestro "objetivo" siempre será el mismo conjunto y con contenido actualizado.


Respuesta anterior usando guión bajo o lodash

Siempre llego aquí desde google y no siempre estoy satisfecho con las respuestas. TU respuesta es buena, pero será más fácil y ordenado usando subrayado.js

DEMO: http://jsfiddle.net/guya/eAWKR/

Aquí hay una función más general que fusionará 2 matrices usando una propiedad de sus objetos. En este caso, la propiedad es 'nombre'

var arr1 = [{name: "lang", value: "English"}, {name: "age", value: "18"}];
var arr2 = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];

function mergeByProperty(arr1, arr2, prop) {
  _.each(arr2, function(arr2obj) {
    var arr1obj = _.find(arr1, function(arr1obj) {
      return arr1obj[prop] === arr2obj[prop];
    });

    arr1obj ? _.extend(arr1obj, arr2obj) : arr1.push(arr2obj);
  });
}

mergeByProperty(arr1, arr2, 'name');

console.log(arr1);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.core.min.js"></script>

[{name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'}]
guya
fuente
6
Casi idéntico en LOC, complejidad que la respuesta de @ YOU, excepto que esto es mucho más lento (en gran parte debido a llamadas de función adicionales y al hecho de que la respuesta de YOU explota el truco de matrices asociativas JS para encontrar elementos con búsqueda O (1)). Esto es además del hecho de que necesita traer una biblioteca adicional.
Mrchief
No obtendría ninguna diferencia en el rendimiento a menos que esté tratando con casos extremos extremos. Con respecto a la lib extra: subrayado, lodash y similares generalmente ya se usan y tienen otros beneficios, uno debería considerar usarlo de todos modos. La mayoría de los desarrolladores y aplicaciones se beneficiarán de la simplicidad y generalidad de esta solución.
guya
1
@guya Me doy cuenta de que esto es antiguo, pero subrayado, lodash y similares generalmente ya se usan y tienen otros beneficios, mientras que, como usted dice, tienen otros beneficios, es una gran suposición decir que generalmente ya se usan.
Craicerjack
26
var arr3 = [];
for(var i in arr1){
   var shared = false;
   for (var j in arr2)
       if (arr2[j].name == arr1[i].name) {
           shared = true;
           break;
       }
   if(!shared) arr3.push(arr1[i])
}
arr3 = arr3.concat(arr2);

ingrese la descripción de la imagen aquí


fuente
1
Esta respuesta tiene una complejidad de tiempo malo (O (n ^ 2)). Es posible una solución O (n) utilizando un mapa hash.
Alex von Brandenfels
19

Muy simple usando el operador de propagación ES6:

const array1 = [{a: 'HI!'}, {b: 'HOW'}]
const array2 = [{c: 'ARE'}, {d: 'YOU?'}]

const mergedArray = [ ...array1, ...array2 ]
console.log('Merged Array: ', mergedArray)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Merged Array: [ {a: 'HI!'}, {b: 'HOW'} {c: 'ARE'}, {d: 'YOU?'} ]

Nota: La solución anterior es simplemente fusionar dos matrices utilizando el operador de propagación ES6.

Edite el 07 de enero de 2020 por @ bh4r4th: como el contexto cambió debido a las ediciones después de mi solución inicial. Me gustaría actualizar mi solución para que coincida con los criterios actuales. es decir,

  1. Fusionar objetos de matriz sin crear objetos duplicados y,

  2. actualizar valuesi la namepropiedad ya existe en la matriz anterior

const arr1 = [
    { name: "lang", value: "English" },
    { name: "age", value: "18" }
]
const arr2 = [
    { name: "childs", value: '2' }, 
    { name: "lang", value: "German" }
]
const arr3 = [
    { name: "lang", value: "German" },
    { name: "age", value: "28" },
    { name: "childs", value: '5' }
]

// Convert to key value dictionary or object
const convertToKeyValueDict = arrayObj => {
    const val = {}
    arrayObj.forEach(ob => {
        val[ob.name] = ob.value
    })
    return val
}

// update or merge array
const updateOrMerge = (a1, a2) => {
    const ob1 = convertToKeyValueDict(a1)
    const ob2 = convertToKeyValueDict(a2)
    // Note: Spread operator with objects used here
    const merged_obj = {...ob1, ...ob2}
    const val = Object.entries(merged_obj)
    return val.map(obj => ({ name: obj[0], value: obj[1] }))
}

const v1 = updateOrMerge(arr1, arr2)
const v2 = updateOrMerge(v1, arr3)
console.log(`Merged array1 and array2: ${JSON.stringify(v1)} \n\n`)
console.log(`Merged above response and array3: ${JSON.stringify(v2)} \n\n`)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

bh4r4th
fuente
1
¡Esta debería ser la respuesta aceptada en 2019! ¡Iba a proponer la misma solución después de ver las otras respuestas con mayor número de votos! @Alexander ¡Es fácil perderse, pero acepta este!
iaforek
Incorrecto. El interrogador desea específicamente REEMPLAZAR objetos si tienen una propiedad duplicada, no simplemente agregarlos.
HaveSpacesuit
Gracias por señalar ese @HaveSpacesuit. Respondí esta pregunta en 2018 cuando el contexto es simplemente fusionar dos matrices. Pronto editará esta respuesta para usar setdespués de la fusión para eliminar duplicados. Esto crearía un nuevo argumento variable pero un código mínimo. Sin embargo, no soy un gran fanático de la carga útil que tiene nombres definidos como propiedades y valores como tipos diferentes. En cambio prefiero [ { lang: &#39;German&#39;, age: 25}] . De esta forma, el peso de la carga útil se minimizará durante la comunicación entre servicios.
bh4r4th
Ahora he actualizado la solución para que coincida con el contexto cambiado de la pregunta.
bh4r4th
16

Fusionando dos matrices:

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var result=arr1.concat(arr2);
// result: [{name: "lang", value: "English"}, {name: "age", value: "18"}, {name : "childs", value: '5'}, {name: "lang", value: "German"}]

Fusionando dos matrices sin valores duplicados para 'nombre':

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var i,p,obj={},result=[];
for(i=0;i<arr1.length;i++)obj[arr1[i].name]=arr1[i].value;
for(i=0;i<arr2.length;i++)obj[arr2[i].name]=arr2[i].value;
for(p in obj)if(obj.hasOwnProperty(p))result.push({name:p,value:obj[p]});
// result: [{name: "lang", value: "German"}, {name: "age", value: "18"}, {name : "childs", value: '5'}]
Andrew D.
fuente
Array.concat es la forma correcta de fusionar 2 matrices en una. También me gusta la suposición extendida de que se abordó el concepto de fusión "verdadera" (en función de una clave determinada de cada elemento de la matriz).
Bob
14

La forma más fácil es con algo de magia ES6:

Fusionar dos con duplicados:

const a = [{a: 1}, {b: 2}]
const b = [{a: 1}]

const result = a.concat(b) // [{a: 1}, {b: 2}, {a: 1}]

Sin duplicados es igual que el anterior más:

const distinct = [...new Set(result.map(item => item.YOUR_PROP_HERE))]

Knikolov
fuente
1
concat no funciona con elementos de diferente naturaleza
fdsfdsfdsfds
7

Con lodash:

_.uniqBy([...arr1, ...arr2], 'name')
Pietro
fuente
que la sintaxis de ES6 funciona con 2 matrices, no con 2 matrices de objetos.
Dario
7

Así es como he abordado un problema similar en un contexto de ES6:

function merge(array1, array2, prop) {
    return array2.map(function (item2) {
        var item1 = array1.find(function (item1) {
            return item1[prop] === item2[prop];
        });
        return Object.assign({}, item1, item2);
    });
}

Nota: Este enfoque no devolverá ningún elemento de array1 que no aparezca en array2.


EDITAR: Tengo algunos escenarios en los que quiero conservar elementos que no aparecen en la segunda matriz, así que se me ocurrió otro método.

function mergeArrays(arrays, prop) {
    const merged = {};

    arrays.forEach(arr => {
        arr.forEach(item => {
            merged[item[prop]] = Object.assign({}, merged[item[prop]], item);
        });
    });

    return Object.values(merged);
}

var arr1 = [
    { name: 'Bob', age: 11 },
    { name: 'Ben', age: 12 },
    { name: 'Bill', age: 13 },
];

var arr2 = [
    { name: 'Bob', age: 22 },
    { name: 'Fred', age: 24 },
    { name: 'Jack', age: 25 },
    { name: 'Ben' },
];

console.log(mergeArrays([arr1, arr2], 'name'));
Marktuk
fuente
6

Otra versión más que usa reduce() method:

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

var arr = arr1.concat(arr2).reduce(function(prev, current, index, array){ 
   
   if(!(current.name in prev.keys)) {
      prev.keys[current.name] = index;
      prev.result.push(current);   
   } 
   else{
       prev.result[prev.keys[current.name]] = current;
   }  

   return prev;
},{result: [], keys: {}}).result;
  
document.getElementById("output").innerHTML = JSON.stringify(arr,null,2);    
<pre id="output"/>

Vadim Gremyachev
fuente
Esto funciono muy bien para mi. Sin embargo, un pequeño problema es que el orden a veces es extraño cuando se combinan 3 objetos json grandes
crh225
5

Solución simple

var tx = [{"id":1},{"id":2}];
var tx1 = [{"id":3},{"id":4}];


var txHistory = tx.concat(tx1)

console.log(txHistory); 
// output
 // [{"id":1},{"id":2},{"id":3},{"id":4}];
Shashwat Gupta
fuente
4

Puede usar un objeto para recopilar sus propiedades mientras reemplaza los duplicados y luego expandir / aplanar ese objeto de nuevo a una matriz. Algo como esto:

function merge(args) {
    args  = Array.prototype.slice.call(arguments);
    var o = { };
    for(var i = 0; i < args.length; ++i)
        for(var j = 0; j < args[i].length; ++j)
            o[args[i][j].name] = args[i][j].value;
    return o;
}

function expand(o) {
    var a = [ ];
    for(var p in o)
        if(o.hasOwnProperty(p))
            a.push({ name: p, value: o[p]});
    return a;
}

var arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
var arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
var arr3 = expand(merge(arr1, arr2));

No sé si esta es la forma más rápida, pero funciona para cualquier cantidad de matrices de entrada; por ejemplo, esto:

var a = expand(
    merge(
        [{name: "lang", value: "English"}, {name: "age", value: "18"}],
        [{name: "childs", value: '5'}, {name: "lang", value: "German"}],
        [{name: 'lang', value: 'Pancakes'}]
    )
);

Te da lo mismo aque estaba enarr3 con "Alemán" reemplazado por "Pancakes".

Este enfoque supone que todos sus objetos tienen la misma {name: ..., value: ...}forma, por supuesto.

Puedes verlo funcionando aquí (abre tu consola por favor): http://jsfiddle.net/ambiguous/UtBbB/

mu es demasiado corto
fuente
2

¿Qué pasa con jQuery Merge?

http://api.jquery.com/jQuery.merge/

Ejemplo de jsFiddle aquí: http://jsfiddle.net/ygByD/

321X
fuente
Eso no reemplazará el inglés con el alemán como se especifica, la fusión se llevará a cabo a lo largo de las namepropiedades.
mu es demasiado corto
¡Ah, sí, tienes razón! ¡No vi esa especificación de un vistazo!
321X
+1. ¡Bien! por otro lado, es una función bastante buena fusionar matrices de objetos de JavaScript
Muhammad Raheel
2

Estaba enfrentando el mismo problema y, según la respuesta de guya , extendí la biblioteca de subrayado y también agregué un poco más de funcionalidad que necesitaba. Aquí está la esencia .

/**
 * Merges two object-like arrays based on a key property and also merges its array-like attributes specified in objectPropertiesToMerge.
 * It also removes falsy values after merging object properties.
 *
 * @param firstArray The original object-like array.
 * @param secondArray An object-like array to add to the firstArray.
 * @param keyProperty The object property that will be used to check if objects from different arrays are the same or not.
 * @param objectPropertiesToMerge The list of object properties that you want to merge. It all must be arrays.
 * @returns The updated original array.
 */
function merge(firstArray, secondArray, keyProperty, objectPropertiesToMerge) {

    function mergeObjectProperties(object, otherObject, objectPropertiesToMerge) {
        _.each(objectPropertiesToMerge, function (eachProperty) {
            object[eachProperty] = _.chain(object[eachProperty]).union(otherObject[eachProperty]).compact().value();
        });
    }

    if (firstArray.length === 0) {
        _.each(secondArray, function (each) {
            firstArray.push(each);
        });
    } else {
        _.each(secondArray, function (itemFromSecond) {
            var itemFromFirst = _.find(firstArray, function (item) {
                return item[keyProperty] === itemFromSecond[keyProperty];
            });

            if (itemFromFirst) {
                mergeObjectProperties(itemFromFirst, itemFromSecond, objectPropertiesToMerge);
            } else {
                firstArray.push(itemFromSecond);
            }
    });
    }

    return firstArray;
}

_.mixin({
            merge: merge
        });

¡Espero que te sea de utilidad! ¡Saludos!

Nahuel Barrios
fuente
2

Recientemente me quedé perplejo con este problema y vine aquí con la esperanza de tener una respuesta, pero la respuesta aceptada usa 2 bucles for in que no preferiría. Finalmente logré hacer el mío. No depende de ninguna biblioteca en absoluto:

function find(objArr, keyToFind){
    var foundPos = objArr.map(function(ob){
        return ob.type;
    }).indexOf(keyToFind);
    return foundPos;
}

function update(arr1,arr2){
    for(var i = 0, len = arr2.length, current; i< len; i++){
        var pos = find(arr1, arr2[i].name); 
        current = arr2[i];
        if(pos !== -1) for(var key in arr2) arr1[pos][key] = arr2[key];
        else arr1[arr1.length] = current;
    } 
}

Esto también mantiene el orden de arr1.

Amin Mohamed Ajani
fuente
2

podrías usar la siguiente función

const merge = (a, b, key = "id") =>
  a.filter(elem => !b.find(subElem => subElem[key] === elem[key]))
   .concat(b);

y prueba

merge(arr1, arr2, 'name');
Diogo Alves
fuente
Gracias a Diago way con la función inmutable de ES6 `` `export const mergeArrays = (a1, a2, key =" id ") => a1 && a2! = Null? [... a1.filter (a =>! a2.find (p => p [clave] === una [clave])), ... a2]: nulo; ``
Musa
1

Aquí primero filtro arr1según el elemento presente arr2o no. Si está presente, no lo agregue a la matriz resultante; de ​​lo contrario, agregue. Y luego agrego arr2al resultado.

arr1.filter(item => {
  if (!arr2.some(item1=>item.name==item1.name)) {
    return item
  }
}).concat(arr2)
maulik bhatt
fuente
Amablemente proporcione la explicación a su respuesta. Entonces, si cualquier otra persona lee la pregunta y responde, entonces se puede entender fácilmente.
Mittal Patel
Si bien esta respuesta probablemente sea correcta y útil, se prefiere si incluye alguna explicación junto con ella para explicar cómo ayuda a resolver el problema. Esto se vuelve especialmente útil en el futuro, si hay un cambio (posiblemente no relacionado) que haga que deje de funcionar y los usuarios deben comprender cómo funcionaba una vez.
Erty Seidohl
Gracias chicos. Actualicé la descripción de la solución. Si parece correcto, por favor
vota hacia arriba
0

Fuera de mi cabeza - prueba jquery extend

var arr3 = jQuery.extend(arr1,arr2....)
Xhalent
fuente
Lo siento. Exactamente esta función devuelve arr4. No $ .merge. El último tampoco me queda bien, porque duplica objetos.
Alexander
0

var newArray = yourArray.concat(otherArray); console.log('Concatenated newArray: ', newArray);

javaScriptBeard
fuente
Estoy de acuerdo en que esto tiene mucho más sentido que la Array.protype.push.apply()respuesta, pero no hace la fusión como OP quería.
keithpjolley
no puede obtener la salida anterior usando 'concat' si tiene dos conjuntos de objetos de combinación. Por favor, revise esto jsfiddle.net/jahanzaibaslam/z22n5tuo
Jahanzaib Aslam
0

Basado en la respuesta de @ YOU pero manteniendo el orden:

var arr3 = [];
for(var i in arr1){
   var shared = false;
   for (var j in arr2)
       if (arr2[j].name == arr1[i].name) {
           arr3.push(arr1[j]
           shared = true;
           break;
       }
   if(!shared) arr3.push(arr1[i])
}

for(var j in arr2){
   var shared = false;
   for (var i in arr1)
       if (arr2[j].name == arr1[i].name) {
           shared = true;
           break;
       }
   if(!shared) arr3.push(arr2[j])
}
arr3

Sé que esta solución es menos eficiente, pero es necesaria si desea mantener el orden y aún actualizar los objetos.

hcarreras
fuente
0

Aquí hay un complemento de jQuery que escribí para fusionar dos matrices de objetos con una clave. Tenga en cuenta que esto modifica la matriz de destino en el lugar.

(function($) {
  $.extendObjectArray = function(destArray, srcArray, key) {
    for (var index = 0; index < srcArray.length; index++) {
      var srcObject = srcArray[index];
      var existObject = destArray.filter(function(destObj) {
        return destObj[key] === srcObject[key];
      });
      if (existObject.length > 0) {
        var existingIndex = destArray.indexOf(existObject[0]);
        $.extend(true, destArray[existingIndex], srcObject);
      } else {
        destArray.push(srcObject);
      }
    }
    return destArray;
  };
})(jQuery);

var arr1 = [
  { name: "lang",   value: "English" },
  { name: "age",    value: "18"      }
];
var arr2 = [
  { name: "childs", value: '5'       },
  { name: "lang",   value: "German"  }
];
var arr3 = $.extendObjectArray(arr1, arr2, 'name');

console.log(JSON.stringify(arr3, null, 2));
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Versión ES6

(function($) {
  $.extendObjectArray = (destArr, srcArr, key) => {
    srcArr.forEach(srcObj => (existObj => {
      if (existObj.length) {
        $.extend(true, destArr[destArr.indexOf(existObj[0])], srcObj);
      } else {
        destArr.push(srcObj);
      }
    })(destArr.filter(v => v[key] === srcObj[key])));
    return destArr;
  };
})(jQuery);
Sr. Polywhirl
fuente
0

Usando lodash quieres _.uniqBy

var arr3 = _.uniqBy(arr1.concat(arr2), 'name'); // es5

let arr3 = _.uniqBy([...arr1, ...arr2], 'name'); // es6

¡El orden de arr1, arr2 importa!

Ver documentos https://lodash.com/docs/4.17.4#uniqBy

danday74
fuente
¿Necesita utilizar un tercero?
Nguyễn Xuân Hoàng
no, pero es la forma más concisa de lograrlo, y no es cualquier tercero, ¡es increíble!
danday74
0
const extend = function*(ls,xs){
   yield* ls;
   yield* xs;
}

console.log( [...extend([1,2,3],[4,5,6])]  );
codemonkey
fuente
2
Simplemente no proporcione la respuesta a la pregunta. También explique cómo esta solución resuelve el problema.
Mittal Patel
0
merge(a, b, key) {
    let merged = [];
    a.forEach(aitem => {
        let found = b.find( bitem => aitem[key] === bitem[key]);
        merged.push(found? found: aitem);
    });
    return merged;
}
Kyaw
fuente
0

Si desea fusionar las 2 matrices, pero eliminar objetos duplicados, use esto. Los duplicados se identifican en .uniqueIdcada objeto

function mergeObjectArraysRemovingDuplicates(firstObjectArray, secondObjectArray) {
  return firstObjectArray.concat(
    secondObjectArray.filter((object) => !firstObjectArray.map((x) => x.uniqueId).includes(object.uniqueId)),
  );
}
daveanderson88
fuente
0

Prueba esto:

var a = [{"a":20, "b":10,"c":"c","d":"asd","f":"any"}]
var b = [{"a":20, "b":10,"c":"c", "e":"nan","g":10200}]

var p = []
_.map(a, function(da){
var chk = _.filter(b, function(ds){
return da.a ===ds.a
})[0]
p.push(_.extend(da, chk))


})

console.log(p)

OutPut será:

  [{
    "a": 20,
    "b": 10,
    "c": "c",
    "d": "asd",
    "f": "any",
    "e": "nan",
    "g": 10200
  }]
Rohit Parte
fuente
0
const arr1 = ["Vijendra","Singh"];
const arr2 = ["Singh", "Shakya"];

arr2.forEach(item => {
        if(!arr1.find(k => k===item))
          arr1.push(item)
    });


console.log(arr1)
Gajju
fuente
0

Solución que utiliza JS Map:

const merge = (arr1, arr2, prop) => {
    const resultMap = new Map([...arr1.map((item) => [item[prop], item])]);
    arr2.forEach((item) => {
        const mapItem = resultMap.get(item[prop]);
        if (mapItem) Object.assign(mapItem, item);
        else resultMap.set(item[prop], item);
    });
    return [...resultMap.values()];
};

const arr1 = new Array({name: "lang", value: "English"}, {name: "age", value: "18"});
const arr2 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});

console.log(merge(arr1, arr2, "name"));

Que produce:

resultado de la función merge ()

2DH
fuente
0
const array1 = [{id:1,name:'ganza'},
{id:2,name:'respice dddd'},{id:4,name:'respice dddd'},{id:6,name:'respice dddd'},
{id:7,name:'respice dddd'}];
const array2 = [{id:1,name:'ganza respice'},{id:2,name:'respice'},{id:3,name:'mg'}];

 function mergeTwoArray(array1,array2){

    return array1.map((item,i)=>{
        if(array2[i] && item.id===array2[i].id){
          return array2[i];
          }else{
            return item;
          }
    });
  }

const result = merge(array1,array2);
console.log(result);
//here is the result:  Array [Object { id: 1, name: "ganza respice" }, Object { id: 2, name: "respice" }, Object { id: 4, name: "respice dddd" }, Object { id: 6, name: "respice dddd" }, Object { id: 7, name: "respice dddd" }]
Respice de Ganza
fuente