Let's say I have two arrays:
let A = [a,b,c,d]
let B = [c,d,e]
where each of the letters is an object that has several properties, one of which is an id
which is unique in my domain. The merged result would then be
[a,b,c,d,e]
where [c,d]
originate from B.
Using an elegant approach, how would I merge these two arrays in a way that any element in B
would overwrite any existing one in A
and all others remain untouched. So it's a union with B
elements taking precedence in case of a conflict.
I have two ideas (using ES6 and lodash):
//remove same elements first, then join arrays
let ids = new Set(B.map(e => e.id));
let newState = _.reject(A, constraint => ids.has(constraint.id));
return newState.concat(B);
//convert both to hashmap, join, then take values
let B_map = _.keyBy(B, 'id');
let A_map = _.keyBy(A, 'id');
return {...A_map, ...B_map}.values();
Is there a shorter / more concise / more readable version? Maybe one without external dependencies? I'm essentially looking for something like
Where equality between any element is defined by the id
property (or a comparator function in v2).
Without external dependencies, you can use filter
to extract elements from A
that don't have ids in B
and concat
that with B
:
const A = [{id: 1, name: 'x'}, {id: 2, name: 'y'}, {id: 3, name: 'z'}];
const B = [{id: 2, name: 'hello'}];
let ids = new Set(B.map(e => e.id));
let newState = A.filter(a => !ids.has(a.id)).concat(B);
console.log(newState);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With