I have two object arrays:
var a = [
{id: 4, name: \'Greg\'},
{id: 1, name: \'David\'},
{id: 2, name: \'John\'},
{id: 3, name: \'Matt\'},
]
var b = [
Here is an attempt at a more generic version of a join which accepts N objects and merges them based on a primary id
key.
If performance is critical, you are better off using a specific version like the one provided by ShadowRanger which doesn't need to dynamically build a list of all property keys.
This implementation assumes that any missing properties should be set to null and that every object in each input array has the same properties (though properties can differ between arrays)
var a = [
{id: 4, name: 'Greg'},
{id: 1, name: 'David'},
{id: 2, name: 'John'},
{id: 3, name: 'Matt'},
];
var b = [
{id: 5, name: 'Mathew', position: '1'},
{id: 600, name: 'Gracia', position: '2'},
{id: 2, name: 'John', position: '2'},
{id: 3, name: 'Matt', position: '2'},
];
console.log(genericJoin(a, b));
function genericJoin(...input) {
//Get all possible keys
let template = new Set();
input.forEach(arr => {
if (arr.length) {
Object.keys(arr[0]).forEach(key => {
template.add(key);
});
}
});
// Merge arrays
input = input.reduce((a, b) => a.concat(b));
// Merge items with duplicate ids
let result = new Map();
input.forEach(item => {
result.set(item.id, Object.assign((result.get(item.id) || {}), item));
});
// Convert the map back to an array of objects
// and set any missing properties to null
return Array.from(result.values(), item => {
template.forEach(key => {
item[key] = item[key] || null;
});
return item;
});
}