How can I perform an inner join with two object arrays in JavaScript?
One of the ways how to solve it.
const a = [
{id: 4, name: 'Greg'},
{id: 1, name: 'David'},
{id: 2, name: 'John'},
{id: 3, name: 'Matt'},
];
const b = [
{id: 5, name: 'Mathew', position: '1'},
{id: 6, name: 'Gracia', position: '2'},
{id: 2, name: 'John', position: '2'},
{id: 3, name: 'Matt', position: '2'},
];
const r = a.filter(({ id: idv }) => b.every(({ id: idc }) => idv !== idc));
const newArr = b.concat(r).map((v) => v.position ? v : { ...v, position: null });
console.log(JSON.stringify(newArr));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I don't know how reduce
would help here, but you could use a Map
to
accomplish the same task in O(n)
:
const a = [
{id: 4, name: 'Greg'},
{id: 1, name: 'David'},
{id: 2, name: 'John'},
{id: 3, name: 'Matt'}];
const b = [
{id: 5, name: 'Mathew', position: '1'},
{id: 6, name: 'Gracia', position: '2'},
{id: 2, name: 'John', position: '2'},
{id: 3, name: 'Matt', position: '2'}];
var m = new Map();
// Insert all entries keyed by ID into the Map, filling in placeholder
// 'position' since the Array 'a' lacks 'position' entirely:
a.forEach(function(x) { x.position = null; m.set(x.id, x); });
// For values in 'b', insert them if missing, otherwise, update existing values:
b.forEach(function(x) {
var existing = m.get(x.id);
if (existing === undefined)
m.set(x.id, x);
else
Object.assign(existing, x);
});
// Extract resulting combined objects from the Map as an Array
var result = Array.from(m.values());
console.log(JSON.stringify(result));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Because Map
accesses and updates are O(1)
(on average - because of hash
collisions and rehashing, it can be longer), this makes O(n+m)
(where n
and m
are the lengths of a
and b
respectively; the naive solution you
gave would be O(n*m)
using the same meaning for n
and m
).