Reputation: 3
I have a dataset like so:
[
{
id: 'abc',
productType: "Nappies"
variants: ['3 Pack of Nappies', 'small']
},
{
id: 'abc',
productType: "Nappies"
variants: ['6 Pack of Nappies', 'small']
},
{
id: 'abc',
productType: "Nappies"
variants: ['12 Pack of Nappies', 'small']
},
{
id: 'abc',
productType: "Nappies"
variants: ['3 Pack of Nappies', 'medium']
},
{
id: 'abc',
productType: "Nappies"
variants: ['6 Pack of Nappies', 'medium']
},
{
id: 'abc',
productType: "Nappies"
variants: ['12 Pack of Nappies', 'medium']
},
{
id: 'def',
productType: "Wipes"
variants: ['3 Pack of Wipes']
},
{
id: 'def',
productType: "Wipes"
variants: ['6 Pack of Wipes']
},
{
id: 'def',
productType: "Wipes"
variants: ['12 Pack of Wipes']
},
]
As you can see, each of the product IDs is repeated across all the variants. I need to reduce the data down so there is only 1 version of each product with the 'X packs of Nappies', eg:
Desired result:
[
{
id: 'abc',
productType: "Nappies"
variants: ['3 Pack of Nappies', 'small']
},
{
id: 'abc',
productType: "Nappies"
variants: ['6 Pack of Nappies', 'small']
},
{
id: 'abc',
productType: "Nappies"
variants: ['12 Pack of Nappies', 'small']
},
{
id: 'def',
productType: "Wipes"
variants: ['3 Pack of Wipes']
},
{
id: 'def',
productType: "Wipes"
variants: ['6 Pack of Wipes']
},
{
id: 'def',
productType: "Wipes"
variants: ['12 Pack of Wipes']
},
]
The secondary variant in each (size, eg 'small'/'medium') is not important. I've tried running a reduce function that runs a filter and returns true if the reduce object's 'variants' property includes any of the active object's 'variant's property but it returns everything.
const RemoveDuplicates = (array) => {
return array.reduce((arr, item) => {
const removed = arr.filter((obj) => {
return obj.selectedOptions.some((i) =>
item.selectedOptions.includes(i)
)
})
return [...removed, item]
}, [])
}
Upvotes: 0
Views: 55
Reputation: 19986
All you have to is to find a match from the accumulator
with below condition
Same id
, same productType
and same variants[0]
Logic
Array.reduce
.acc
is accumulator, which holds the list of accumulation. Next parameter curr
is the current value which holds each node of the array while looping. What you have to do is to push the current value to the accumulator if the requirement is satisfied.curr
value is there in the acc
. If there is a node in the accumulator
against each curr
having same id
, productType
and variants[0]
which you call as the version. If the accumulator already have a node with the matching combination, dont push the current value to the accumulator
.const input = [
{ id: 'abc', productType: "Nappies", variants: ['3 Pack of Nappies', 'small'] },
{ id: 'abc', productType: "Nappies", variants: ['6 Pack of Nappies', 'small'] },
{ id: 'abc', productType: "Nappies", variants: ['12 Pack of Nappies', 'small'] },
{ id: 'abc', productType: "Nappies", variants: ['3 Pack of Nappies', 'medium'] },
{ id: 'abc', productType: "Nappies", variants: ['6 Pack of Nappies', 'medium'] },
{ id: 'abc', productType: "Nappies", variants: ['12 Pack of Nappies', 'medium'] },
{ id: 'def', productType: "Wipes", variants: ['3 Pack of Wipes'] },
{ id: 'def', productType: "Wipes", variants: ['6 Pack of Wipes'] },
{ id: 'def', productType: "Wipes", variants: ['12 Pack of Wipes'] },
];
const output = input.reduce((acc, curr) => {
const node = acc.find((item) =>
item.id === curr.id &&
item.productType === curr.productType &&
item.variants[0] === curr.variants[0]);
if(!node) {
acc.push(curr)
}
return acc;
}, []);
console.log(output);
Upvotes: 1
Reputation: 12909
You can do this as a standard group-by with a composite key, but instead of accumulating, use the key as a check for duplicates.
const input = [ { id: 'abc', productType: "Nappies", variants: ['3 Pack of Nappies', 'small'] }, { id: 'abc', productType: "Nappies", variants: ['6 Pack of Nappies', 'small'] }, { id: 'abc', productType: "Nappies", variants: ['12 Pack of Nappies', 'small'] }, { id: 'abc', productType: "Nappies", variants: ['3 Pack of Nappies', 'medium'] }, { id: 'abc', productType: "Nappies", variants: ['6 Pack of Nappies', 'medium'] }, { id: 'abc', productType: "Nappies", variants: ['12 Pack of Nappies', 'medium'] }, { id: 'def', productType: "Wipes", variants: ['3 Pack of Wipes'] }, { id: 'def', productType: "Wipes", variants: ['6 Pack of Wipes'] }, { id: 'def', productType: "Wipes", variants: ['12 Pack of Wipes'] },];
const output = Object.values(input.reduce((a, c) => {
const key = `${c.id}_${c.productType}_${c.variants[0]}`;
if (!a.hasOwnProperty(key)) {
a[key] = {...c};
}
return a;
}, {}));
console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0