Mesclar 2 matrizes de objetos

112

Vamos dar uma olhada em um exemplo.

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

Preciso mesclar essas 2 matrizes de objetos e criar a seguinte matriz:

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

Existe alguma função JavaScript ou jQuery para fazer isso?

$.extendnão combina comigo. Retorna

arr4 = new Array({name : "childs", value: '5'}, {name: "lang", value: "German"});
Alexandre
fonte
15
O que aconteceu {name: "lang", value: "English"}?
Shadow Wizard is Ear For You
Desculpe. I mento $ .extend, não $ .merge.
Alexander
1
Quer dizer, qual é a lógica envolvida? Como você deseja mesclar os arrays? Não está claro em seus exemplos.
Shadow Wizard is Ear For You
Muito obrigado a todos. Eu fiz isso manualmente.
Alexander
6
@ShadowWizard, acho que o que o OP significava era atualizar se existe e push se não existir.
Amin Mohamed Ajani

Respostas:

84

Se você deseja mesclar 2 arrays de objetos em JavaScript. Você pode usar este truque de uma linha

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

Por exemplo

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

Resultado:

[{"name":"lang","value":"English"},
{"name":"age","value":"18"},
{"name":"childs","value":"5"},
{"name":"lang","value":"German"}]
Jahanzaib Aslam
fonte
Este é até agora o uso mais simples e funciona muito bem. Obrigado por compartilhar isso.
Leo Caseiro
17
mesmo resultado que o muito mais simples:arr1 = arr1.concat(arr2)
keithpjolley
7
mas isso não é fusão!
Dimitri Kopriwa
1
Os resultados não são os mesmos. concatretornará uma nova matriz e quebrará todas as referências que você tinha.
Bpainter
8
Isso não responde à pergunta, a matriz resultante deve ter 3 objetos, não 4. Você alterou os valores de amostra. Basicamente, o que o OP deseja é fundir duas matrizes de objetos e remover valores duplicados.
Ranjan de
43

Com ES6, você pode fazer isso muito facilmente, conforme abaixo:

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

Resultado:

    arr3 = [
      {"name":"lang","value":"German"},
      {"name":"age","value":"18"},
      {"name":"childs","value":"5"},
      {"name":"lang","value":"German"}
    ]
Nguyễn Bá Vinh
fonte
6
Esta deve ser a melhor resposta.
nocdib
20
Isso não faz o que o OP estava procurando, não deveria haver um segundo objeto contendo{ name: 'lang', value: 'German'}
Será
3
Não sei por que essa resposta foi votada. O que @ daveanderson88 deseja é diferente dessa resposta.
Nguyễn Xuân Hoàng
33

Para aqueles que estão experimentando coisas 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"
//     }
// ]
prumo
fonte
29

Atualização 12 de outubro de 2019

Nova versão baseada apenas em Javascript mais recente e sem a necessidade de qualquer biblioteca de terceiros.

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)

Essa resposta estava ficando velha, libs como lodash e underscore são muito menos necessárias hoje em dia. Nesta nova versão, o array target (arr1) é aquele com o qual estamos trabalhando e queremos manter atualizado. A matriz de origem (arr2) é de onde os novos dados estão vindo, e queremos que sejam mesclados em nossa matriz de destino .

Fazemos um loop sobre o array de origem procurando novos dados e, para cada objeto que ainda não foi encontrado em nosso array de destino , simplesmente adicionamos esse objeto usando target.push (sourceElement) If, com base em nossa propriedade de chave ('nome') , um object já está em nosso array de destino - atualizamos suas propriedades e valores usando Object.assign (targetElement, sourceElement) . Nosso “target” será sempre o mesmo array e com conteúdo atualizado.


Resposta antiga usando sublinhado ou lodash

Sempre chego aqui do google e nem sempre fico satisfeito com as respostas. SUA resposta é boa, mas será mais fácil e mais organizada usando o underscore.js

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

Aqui está uma função mais geral que mesclará 2 arrays usando uma propriedade de seus objetos. Neste caso, a propriedade é 'nome'

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
fonte
6
Quase idêntico em LOC, complexidade como resposta de @ YOU, exceto que isso é muito mais lento (em grande parte devido a chamadas de funções extras e o fato de que a resposta de YOU explora o truque de matrizes associativas JS para encontrar itens com pesquisa O (1)). Além do fato de que você precisa trazer uma biblioteca adicional.
Mrchief de
Você não conseguiria nenhuma diferença no desempenho, a menos que esteja lidando com casos extremos. Em relação à lib extra - sublinhado, lodash e similares geralmente já são usados ​​e têm outros benefícios, deve-se considerar o uso de qualquer maneira. A maioria dos desenvolvedores e aplicativos se beneficiará da simplicidade e generalidade desta solução.
guya
1
@guya Sei que isso é antigo, mas sublinhado, lodash e similares geralmente já são usados ​​e têm outros benefícios, enquanto você disse que eles têm outros benefícios, é uma grande suposição dizer que geralmente já são usados.
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);

insira a descrição da imagem aqui

VOCÊS
fonte
1
Esta resposta tem complexidade de tempo ruim (O (n ^ 2)). Uma solução O (n) é possível usando um mapa hash.
Alex von Brandenfels
18

Muito simples usando o operador de propagação 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: A solução acima é apenas mesclar duas matrizes usando o operador de propagação ES6.

Editar em 07 de janeiro de 2020 por @ bh4r4th: Como o contexto mudou devido a edições após minha solução inicial. Eu gostaria de atualizar minha solução para corresponder aos critérios atuais. ou seja,

  1. Mesclar objetos de matriz sem criar objetos duplicados e,

  2. atualize valuese a namepropriedade já existir na 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
fonte
1
Essa deve ser a resposta aceita em 2019! Eu iria propor a mesma solução depois de olhar para as outras respostas com maior contagem de votos! @Alexander É fácil perder, mas por favor aceite este!
iaforek
Incorreta. O questionador deseja especificamente SUBSTITUIR objetos se eles tiverem uma propriedade duplicada, não simplesmente anexá-los.
HaveSpacesuit
Obrigado por apontar aquele @HaveSpacesuit. Eu respondi a essa pergunta em 2018, quando o contexto é apenas mesclar dois arrays. Editarei esta resposta em breve para usar setna mesclagem para remover duplicatas. Isso criaria um novo argumento de variável, mas código mínimo. No entanto, não sou um grande fã de carga útil, que tem nomes definidos como propriedades e valores como tipos diferentes. Em vez disso, prefiro [ { lang: &#39;German&#39;, age: 25}] . Desta forma, o peso da carga útil será minimizado durante a comunicação entre os serviços.
bh4r4
Agora atualizei a solução para corresponder ao contexto alterado da questão.
bh4r4 de
16

Mesclando duas matrizes:

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"}]

Mesclando duas matrizes sem valores duplicados para 'nome':

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.
fonte
Array.concat é a maneira adequada de mesclar 2 arrays em um. Também gosto da suposição estendida de que o conceito de mesclagem "verdadeira" foi abordado (com base em uma determinada chave de cada elemento do array).
bob
14

A maneira mais fácil é com alguma magia ES6:

Mesclar dois com duplicatas:

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

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

Sem duplicatas, é igual ao anterior, mais:

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

Knikolov
fonte
1
concat não funciona com itens de naturezas diferentes
fdsfdsfdsfds
7

Com lodash:

_.uniqBy([...arr1, ...arr2], 'name')
Pietro
fonte
que a sintaxe ES6 funciona com 2 arrays, não com 2 arrays de objetos.
Dario
7

É assim que lidei com um problema semelhante em um contexto 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: Esta abordagem não retornará nenhum item da matriz1 que não apareça na matriz2.


EDIT: Eu tenho alguns cenários em que desejo preservar itens que não aparecem na segunda matriz, então eu vim com outro 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
fonte
6

Ainda outra versão usando 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
fonte
Isso funcionou muito bem para mim. Um pequeno problema, porém, é que a ordem às vezes é estranha ao mesclar 3 grandes objetos json
crh225 01 de
5

Solução simples

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
fonte
4

Você pode usar um objeto para coletar suas propriedades enquanto substitui duplicatas e, em seguida, expandir / nivelar esse objeto de volta para uma matriz. Algo assim:

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

Não sei se esta é a maneira mais rápida, mas funciona para qualquer número de matrizes de entrada; por exemplo, este:

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

Dá a você a mesma coisa aque estava emarr3 com "Alemão" substituído por "Panquecas".

Essa abordagem pressupõe que todos os seus objetos tenham a mesma {name: ..., value: ...}forma, é claro.

Você pode vê-lo funcionando aqui (abra seu console, por favor): http://jsfiddle.net/ambiguous/UtBbB/

mu é muito curto
fonte
2

E sobre o jQuery Merge?

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

Exemplo de jsFiddle aqui: http://jsfiddle.net/ygByD/

321X
fonte
Isso não substituirá o inglês pelo alemão, conforme especificado, a fusão ocorre ao longo das namepropriedades.
mu é muito curto
AH sim, você está certo! Não vi essa especificação à primeira vista!
321X de
+1. Bem! por outro lado, é uma função muito boa mesclar matrizes javascript de objetos
Muhammad Raheel
2

Eu estava enfrentando o mesmo problema e com base na resposta de guya , estendi a biblioteca de sublinhados e também adicionei um pouco mais de funcionalidade que estava exigindo. Aqui está a essência .

/**
 * 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 seja útil! Saudações!

Nahuel Barrios
fonte
2

Recentemente, fiquei perplexo com esse problema e vim aqui com a esperança de ter uma resposta, mas a resposta aceita usa 2 for em loops, o que eu não preferiria. Finalmente consegui fazer o meu. Não depende de nenhuma biblioteca:

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

Isso também mantém a ordem de arr1.

Amin Mohamed Ajani
fonte
2

você poderia usar a seguinte função

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

e tentar

merge(arr1, arr2, 'name');
Diogo Alves
fonte
Graças à maneira Diago com o recurso imutável ES6 `` `export const mergeArrays = (a1, a2, key =" id ") => a1 && a2! = Null? [... a1.filter (a =>! a2.find (p => p [chave] === a [chave])), ... a2]: nulo; `` `
Musa
1

Aqui, primeiro filtro com arr1base no elemento presente arr2ou não. Se estiver presente, não o adicione ao array resultante, caso contrário, adicione. E então acrescento arr2ao resultado.

arr1.filter(item => {
  if (!arr2.some(item1=>item.name==item1.name)) {
    return item
  }
}).concat(arr2)
Maulik Bhatt
fonte
Forneça a explicação para sua resposta. Portanto, se qualquer outra pessoa ler a pergunta e responder, ela poderá ser facilmente compreendida.
Mittal Patel
Embora essa resposta provavelmente seja correta e útil, é preferível incluir alguma explicação com ela para explicar como ela ajuda a resolver o problema. Isso se torna especialmente útil no futuro, se houver uma mudança (possivelmente não relacionada) que faça com que ele pare de funcionar e os usuários precisem entender como funcionava antes.
Erty Seidohl
Obrigado pessoal. Eu atualizei a descrição da solução. Se parecer correto, por
favor
0

Em cima da minha cabeça - tente jquery extend

var arr3 = jQuery.extend(arr1,arr2....)
Xhalent
fonte
Desculpe. Exatamente essa função retorna arr4. Não $ .merge. O último também não combina comigo, pois duplica objetos.
Alexander
0

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

javaScriptBeard
fonte
concordo que isso faz muito mais sentido do que a Array.protype.push.apply()resposta, mas não faz a mesclagem como o OP queria.
keithpjolley de
você não pode obter a saída acima usando 'concat' se tiver duas matrizes de mesclagem de objetos. Verifique jsfiddle.net/jahanzaibaslam/z22n5tuo
Jahanzaib Aslam
0

Com base na resposta de @ YOU, mas mantendo a ordem:

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

Sei que essa solução é menos eficiente, mas é necessária se você quiser manter a ordem e ainda atualizar os objetos.

hcarreras
fonte
0

Aqui está um plugin jQuery que escrevi para mesclar duas matrizes de objetos por uma chave. Lembre-se de que isso modifica a matriz de destino no local.

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


Versão 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
fonte
0

Usando lodash, você deseja _.uniqBy

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

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

Ordem de arr1, arr2 importa!

Veja os documentos https://lodash.com/docs/4.17.4#uniqBy

danday74
fonte
precisa usar terceiros?
Nguyễn Xuân Hoàng
não, mas é a maneira mais concisa de alcançá-lo, e não é qualquer terceiro, é o lodash!
danday74
0
const extend = function*(ls,xs){
   yield* ls;
   yield* xs;
}

console.log( [...extend([1,2,3],[4,5,6])]  );
codemonkey
fonte
2
Apenas não forneça a resposta à pergunta. Explique também como essa solução resolve o 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
fonte
0

Se você quiser mesclar os 2 arrays, mas remover objetos duplicados, use isso. Duplicados são identificados em .uniqueIdcada objeto

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

Experimente isto:

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
fonte
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
fonte
0

Solução utilizando 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 produz:

resultado da função merge ()

2DH
fonte
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" }]
Ganza respice
fonte