Home > database >  How to merge two arrays using a property?
How to merge two arrays using a property?

Time:10-13

I want to create an (output) array of objects from one or multiple other (input) arrays.

For two input arrays defined as:

var array1 = [
    { id: 1, name: 'a1'},
    { id: 2, name: 'a2'},
    { id: 3, name: 'a3'},
    { id: 4, name: 'a4'},
    { id: 5, name: 'a5'},
];

var array2 = [
    { id: 1, name: 'a1', sub: { data: 'we' } },
    { id: 2, name: 'a2', sub: { data: 'dfd' } },
    { id: 5, name: 'a5', sub: { data: 'vbf' } },
];

...the resulting (output) array should be:

var newarray = [
    { id: 1, name: 'a1', sub: { data: 'we' } },
    { id: 2, name: 'a2', sub: { data: 'dfd' } },
    { id: 3, name: 'a3', sub: {}},
    { id: 4, name: 'a4', sub: {}},
    { id: 5, name: 'a5', sub: { data: 'vbf' } },
];

I have tried the following but there is a mistake there somewhere:

var newarray = [];
var oArray = {};
for(var i = 0; i <= array1.length;) {
    for(var j = 0; j <= array2.length; j  ) {
        if(array1[i].id === array2[j].id) {
            oArray = {
                "id":  array1[i].id,
                 "name": array1[i].name,
                 "sub": array1[i].sub 
            };
            newarray.push(oArray);
            i  ;
            break;
        } else {  
            oArray = {
                    "id":  array1[i].id,
                     "name": array1[i].name,
                     "sub": array1[i].sub 
                };
                newarray.push(oArray);
        }
    }
}

CodePudding user response:

You could use map to go over the array and find to find the corresponding item and then merge them how you like.

const array1 = [
    { id: 1, name: 'a1'},
    { id: 2, name: 'a2'},
    { id: 3, name: 'a3'},
    { id: 4, name: 'a4'},
    { id: 5, name: 'a5'},
];

const array2 = [
    { id: 1, name: 'a1', sub: { data: 'we' } },
    { id: 2, name: 'a2', sub: { data: 'dfd' } },
    { id: 5, name: 'a5', sub: { data: 'vbf' } },
];

const outcome = array1.map((x) => {
  const corresponding = array2.find((y) => y.name === x.name);
  return { ...x, sub: corresponding ? corresponding.sub : {} }
});

console.log(outcome);

CodePudding user response:

You shouldreally make sure that the index limits for your loops are correct. <=length will cause a problem in any array.

Also, I would suggest first pushing into the array from array1, and then in the inner loop searching in the array to find matching id from array1. And simply updating.

var array1 = [
    { id: 1, name: 'a1'},
    { id: 2, name: 'a2'},
    { id: 3, name: 'a3'},
    { id: 4, name: 'a4'},
    { id: 5, name: 'a5'},
];

var array2 = [
    { id: 1, name: 'a1', sub: { data: 'we' } },
    { id: 2, name: 'a2', sub: { data: 'dfd' } },
    { id: 5, name: 'a5', sub: { data: 'vbf' } },
];

var newarray = [];
for(var i = 0; i < array1.length;i  ) {            
   let oArray = {
       "id":  array1[i].id,
       "name": array1[i].name,
       "sub": {} 
   };
   newarray.push(oArray);
   for(var j = 0; j < array2.length; j  ) {
       if(array1[i].id === array2[j].id) {
           let found = newarray.find(x => x.id === array2[j].id);
           if(found) found.sub =array2[j].sub;
        } 
    }
}
console.log(newarray);

let found = newarray.find(x => x.id === array2[j].id);

find() is used to find and return something on the array based on the specific condition. If the inner function returns true for any array index, the element at that index is returned. In our condition, we check to match the id and return based on that. So found is finally the found item based on condition. That is why only if it exists, we are accessing its property. If not found, found becomes undefined.

Above arrow function could well be written as:

let found = newarray.find(function (x) { return (x.id === array2[j].id) });

There are a lot of other ways to do it, but this one is closest to your approach and improves upon it.

CodePudding user response:

I used a map function instead of a for-loop. Here is my solution :

var array1 = [
    { id: 1, name: 'a1'},
    { id: 2, name: 'a2'},
    { id: 3, name: 'a3'},
    { id: 4, name: 'a4'},
    { id: 5, name: 'a5'},
];

var array2 = [
    { id: 1, name: 'a1', sub: { data: 'we' } },
    { id: 2, name: 'a2', sub: { data: 'dfd' } },
    { id: 5, name: 'a5', sub: { data: 'vbf' } },
];



let noSubs = array1.filter(el => ! array2.map(element => element.id).includes(el.id));
let newArray = noSubs.concat(array2);
console.log(newArray);

CodePudding user response:

Try this one

function merge(a, b) {
    for (let i=0;i<a.length;i  ) {
        let cu = b.find(d => d.id == a[i].id);
        if (cu) {
            a[i] = {...a[i], ...cu};
        }
    }
    return a;
}

let arr1 = [
    {id: 1, name: "a1"},
    {id: 2, name: "a2"},
    {id: 3, name: "a3"},
    {id: 4, name: "a4"},
    {id: 5, name: "a5"},
];

let arr2 = [
    {id: 1, name: "a1", sub: {data: "we"}},
    {id: 2, name: "a2", sub: {data: "dfd"}},
    {id: 5, name: "a5", sub: {data: "vbf"}},
];

let outcome = merge(arr1, arr2);
console.log(outcome);

  • Related