Reputation: 643
I have an array of objects
const data = [{
productId: 7000254,
quantity: 1
}, {
productId: 7000255,
quantity: 1
}, {
productId: 7000256,
quantity: 1
}, {
productId: 7000257,
quantity: 1
}, {
productId: 7000254,
quantity: 1
}];
I need to get unique values from it using the reduce function.
I made it using below code
data.map((rp) => {
if (products.map(({ productId }) => productId).indexOf(rp.productId) === -1) {
products.push({ productId: parseInt(rp.productId), quantity: 1 })
}
})
but as you can see it's a lengthy process because I have to iterate over the array multiple times. So is there any way using reduce function?
var unique = data.reduce((a, b ,c,d) => {
if (a.map(({productId}) => productId).indexOf(b.productId) === -1) {
return [a,b]
}
})
console.log(unique)
Expected output
0: {productId: 7000254, quantity: 1}
1: {productId: 7000255, quantity: 1}
2: {productId: 7000256, quantity: 1}
3: {productId: 7000257, quantity: 1}
Upvotes: 0
Views: 2302
Reputation: 643
Best way to do this without iterating multiple times is to use reduce something like this
const output = data.reduce((pv, cv) => (
pv.array.indexOf(cv.productId) === -1) // new value
? {
array: [...pv.array, cv.productId],
output: [...pv.output, cv]
}
: pv
), { array: [], output: [] })
console.log({ output })
Upvotes: 0
Reputation: 19986
Array.reduce
implementation.
Logic
const data = [{
productId: 7000254,
quantity: 1
}, {
productId: 7000255,
quantity: 1
}, {
productId: 7000256,
quantity: 1
}, {
productId: 7000257,
quantity: 1
}, {
productId: 7000254,
quantity: 1
}];
const output = data.reduce((acc, curr) => {
const matchingNode = acc.find(node => node.productId === curr.productId);
if(!matchingNode) {
acc.push(curr);
}
return acc;
}, []);
console.log(output)
Upvotes: 0
Reputation: 25408
You can efficiently achieve this result using filter and Set.
const data = [{
productId: 7000254,
quantity: 1,
},
{
productId: 7000255,
quantity: 1,
},
{
productId: 7000256,
quantity: 1,
},
{
productId: 7000257,
quantity: 1,
},
{
productId: 7000254,
quantity: 1,
},
];
const set = new Set();
const result = data.filter((o) => {
if (set.has(o.productId)) return false;
set.add(o.productId);
return true;
});
console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}
Upvotes: 2