The title is very wordy, so I will demonstrate the idea with an example and a working code:
Consider a large song library available in a store. Lets call it "bigarray". A client has his/her own personal library of purchased songs from that store: "smallArray". BigArray elements has a property "purchased". I need to set that property to "true" if there is a match by id between songs of both arrays. A working code example:
for (let i = 0; i < bigArray.length; i++) {
for (let j = 0; j < smallArray.length; j++) {
if (bigArray[i].id === smallArray[j].id) {
bigArray[i].purchased = true;
}
}
}
Is there a way to program that using array methods like map, filter etc. with predicate functions possibly in one line, instead of a double for loop?
You could first create a set of ids from the objects in your smallArray
, then use .map()
on your bigArray
to update the purchased
property to true
or false
based on whether the set has the id of the current object from the big array:
const smallSet = new Set(smallArray.map(({id}) => id));
const result = bigArray.map(obj => ({...obj, purchased: smallSet.has(obj.id)}));
You could also use .some()
to determine if your smallArray
has an object that matches an id from your bigArray
, this has a worse time-complexity of O(n*k) compared to using the set which is O(n+k), but is more suitable for a "one-liner" if that's what you're after:
const result = bigArray.map(obj => ({
...obj,
purchased: smallArray.some(item => item.id === obj.id)
}));
Both of these create new object references for each object in the new array, even if you're not updating the purchased
property. To create new objects just for the object you're updating, you can use the result of .has()
or .some()
as the conditional operand like so:
bigArray.map(obj => smallSet.has(obj.id) ? {...obj, purchased: true} : obj);