我想组合数组中的对象,应该如何更改?
I want to combine the objects in the array, how should I change them?
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) {
???
}
}, []);
输出
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
option: [
{ optionName: "13inch", optionPrice: 0, qty: 2 },
{ optionName: "15inch", optionPrice: 1000, qty: 1 },
],
},
如果productId与上面代码相同,
我想去掉key:value的重叠部分,为不重叠的部分创建一个option对象,为value创建一个数组对象。
我试着用reduce解决了,但是不太顺利,所以我问你一个问题。
一种方法是将array转为object,使用productId
作为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);
这是一种不会改变现有数组数据的任何部分的纯函数式方法:
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);
这是您可以做到的一种方法:
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, }, ],
output = Object.entries(
data.reduce(
(prev,{productId,...r}) =>
({...prev, [productId]: Object.entries(r).reduce(
(acc,[key,value]) =>
({...acc, [key]: prev[productId] && prev[productId][key] ?
prev[productId][key] === value ?
value :
[prev[productId][key],value] :
value
}),{})
}),{}
)
)
.map(
([productId,obj]) =>
({
productId,
...Object.entries(obj).reduce(
(acc,[key,value]) =>
!Array.isArray(value) ?
({...acc, [key]:value}) :
({...acc, option:value.map(
(v,i) =>
acc["option"] ?
({...acc["option"][i], [key]: v}) :
({[key]: v}))
}),
{})
})
);
console.log(output);
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) {
???
}
}, []);
输出
{
productId: 6,
productName: "pouch",
productPrice: 29000,
discountRate: 19,
option: [
{ optionName: "13inch", optionPrice: 0, qty: 2 },
{ optionName: "15inch", optionPrice: 1000, qty: 1 },
],
},
如果productId与上面代码相同,
我想去掉key:value的重叠部分,为不重叠的部分创建一个option对象,为value创建一个数组对象。
我试着用reduce解决了,但是不太顺利,所以我问你一个问题。
一种方法是将array转为object,使用productId
作为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);
这是一种不会改变现有数组数据的任何部分的纯函数式方法:
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);
这是您可以做到的一种方法:
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, }, ],
output = Object.entries(
data.reduce(
(prev,{productId,...r}) =>
({...prev, [productId]: Object.entries(r).reduce(
(acc,[key,value]) =>
({...acc, [key]: prev[productId] && prev[productId][key] ?
prev[productId][key] === value ?
value :
[prev[productId][key],value] :
value
}),{})
}),{}
)
)
.map(
([productId,obj]) =>
({
productId,
...Object.entries(obj).reduce(
(acc,[key,value]) =>
!Array.isArray(value) ?
({...acc, [key]:value}) :
({...acc, option:value.map(
(v,i) =>
acc["option"] ?
({...acc["option"][i], [key]: v}) :
({[key]: v}))
}),
{})
})
);
console.log(output);