const data = [
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
optionName: "13inch",
optionPrice: 0,
qty: 2,
},
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
optionName: "15inch",
optionPrice: 1000,
qty: 1,
},
]
const results = data.reduce((prev, curr) => {
if (prev.productId === curr.productId) {
???
}
}, []);
output
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
option: [
{ optionName: "13inch", optionPrice: 0, qty: 2 },
{ optionName: "15inch", optionPrice: 1000, qty: 1 },
],
},
If the productId is the same as the code above,
I want to remove the overlapping part of key:value, create an option object for the non-overlapping part, and create an array object for value.
I tried to solve it by using reduce, but it didn't go well, so I'm asking you a question.
CodePudding user response:
One method is to convert array into object, and use productId
as key:
const data = [
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
optionName: "13inch",
optionPrice: 0,
qty: 2,
},
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
optionName: "15inch",
optionPrice: 1000,
qty: 1,
},
{
productId: 4,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
optionName: "15inch",
optionPrice: 1000,
qty: 1,
},
]
const results = Object.values(data.reduce((prev, curr) => {
if (prev[curr.productId])
{
const obj = prev[curr.productId];
if (!obj.option)
{
obj.option = [];
obj.option.push({optionName: obj.optionName, optionPrice: obj.optionPrice, qty: obj.qty});
delete obj.optionName;
delete obj.optionPrice;
delete obj.qty;
}
prev[curr.productId].option.push({optionName: curr.optionName, optionPrice: curr.optionPrice, qty: curr.qty});
}
else
prev[curr.productId] = Object.assign({}, curr);
return prev;
}, {}));
console.log(results);
CodePudding user response:
Here's a pure, functional approach which won't mutate any part of your existing array data:
function deduplicate (array) {
const results = [];
const idCache = new Set();
for (const item of array) {
// skip if we've already seen products with the same ID
if (idCache.has(item.productId)) continue;
idCache.add(item.productId);
// get products with matching ID
const items = array.filter(({productId}) => productId === item.productId);
// if there were none, store the single product as-is and continue
if (items.length === 0) {
results.push({...item});
continue;
}
// add initial product to others, preserving order
items.unshift(item);
const merged = {};
for (const key of Object.keys(item)) {
const values = items.map(item => item[key]);
// if all the same value, set it on the merged object
if (values.every(val => val === item[key])) merged[key] = item[key];
else {
// set to property on obj in "options" array
for (const [idx, val] of values.entries()) {
((merged.options ??= [])[idx] ??= {})[key] = val;
}
}
}
results.push(merged);
}
return results;
}
const data = [
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
optionName: "13inch",
optionPrice: 0,
qty: 2,
},
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
optionName: "15inch",
optionPrice: 1000,
qty: 1,
},
{
productId: 5,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
optionName: "15inch",
optionPrice: 1000,
qty: 1,
},
];
const result = deduplicate(data);
console.log(result);