将所有键合并到 JavaScript 中具有相同 Id 的单个对象
Merge all keys into single object with the same Id in JavaScript
我有一组类似的对象。
var orderResults = [{
id: '1',
name: 'Maya Mahardhani',
payment_amount : 100,
sku: 'ST001802027',
seq: '1'
},
{
id: '1',
name: 'Maya Mahardhani',
payment_amount : 50,
sku: 'ST000703044',
seq: '2'
},
{
id: '2',
name: 'Tara Debu Batara',
payment_amount : 100,
sku: 'ST005101001',
seq: '1'
},
{
id: '3',
name: 'Nikita Gigir',
payment_amount : 100,
sku: 'ST004403030',
seq: '1'
}]
但我正在尝试通过以下方式提取数据。
[{
id: '1',
name: 'Maya Mahardhani',
total_amount : 150,
sku_1: 'ST001802027',
sku_2: 'ST000703044',
},
{
id: '2',
name: 'Tara Debu Batara',
total_amount : 100,
sku_1: 'ST005101001'
},
{
id: '3',
name: 'Nikita Gigir',
total_amount : 100,
sku_1: 'ST004403030'
}]
我尝试使用 JavaScript 的 reduce
函数。但是它会用旧的覆盖 prev 键。我的代码片段就是这样。我想我更接近解决。但仍在寻求帮助
orderResults.reduce((res, obj) => {
res[obj.id] = {
total_amount : (obj.id in res ? res[obj.id].total_amount : 0) + obj.payment_amount,
name : obj.name,
}
res[obj.id]['sku' + obj.seq]= obj.sku
return res;
},[])
谢谢
我认为这会完成您想要做的事情:
orderResults.reduce((res, obj, i) => {
const existingIdx = res.findIndex(r => r.id === obj.id)
if (existingIdx > -1) {
res[existingIdx] = {
...res[existingIdx],
total_amount : res[existingIdx].total_amount ? res[existingIdx].total_amount + obj.payment_amount : res[existingIdx].payment_amount + obj.payment_amount,
name : obj.name,
['sku_' + obj.seq]: obj.sku
}
} else {
res.push({
id: obj.id,
name: obj.name,
total_amount: obj.payment_amount,
['sku_' + obj.seq]: obj.sku
})
}
return res;
},[])
注意此行将保留原始对象并覆盖之后定义的任何重复键:
...res[existingIdx],
此外,当您的代码运行此行时:
res[obj.id] = {
它正在数组中设置一个特定的索引,我认为你不想这样做。您想要推送(如果尚未添加对象 ID),或者在创建具有相同 ID 的对象时覆盖原始插入点处的现有对象。
不要每次都创建一个新对象。
const result = Object.values(orderResults.reduce((res, obj) => {
res[obj.id] = res[obj.id] ||
{
id: obj.id,
total_amount : 0,
name : obj.name,
};
res[obj.id].total_amount += obj.total_amount;
res[obj.id]['sku' + obj.seq] = obj.sku;
return res;
},[]))
[{
id: '1',
name: 'Maya Mahardhani',
payment_amount: 100,
sku: 'ST001802027',
seq: '1'
},
{
id: '1',
name: 'Maya Mahardhani',
payment_amount: 50,
sku: 'ST000703044',
seq: '2'
},
{
id: '2',
name: 'Tara Debu Batara',
payment_amount: 100,
sku: 'ST005101001',
seq: '1'
},
{
id: '3',
name: 'Nikita Gigir',
payment_amount: 100,
sku: 'ST004403030',
seq: '1'
}].reduce((acc, current) => {
const { id, name, payment_amount, sku, seq } = current;
const previousRecord = acc[id];
if (typeof previousRecord === 'object') {
return {
...acc,
[id]: {
...previousRecord,
[`sku_${seq}`]: sku,
total_amount: previousRecord.total_amount + payment_amount
}
}
} else {
return {
...acc,
[id]: {
id,
name,
[`sku_${seq}`]: sku,
total_amount: payment_amount
}
}
}
}, {}) // returns an Object; use Object.values to convert to a list
我有一组类似的对象。
var orderResults = [{
id: '1',
name: 'Maya Mahardhani',
payment_amount : 100,
sku: 'ST001802027',
seq: '1'
},
{
id: '1',
name: 'Maya Mahardhani',
payment_amount : 50,
sku: 'ST000703044',
seq: '2'
},
{
id: '2',
name: 'Tara Debu Batara',
payment_amount : 100,
sku: 'ST005101001',
seq: '1'
},
{
id: '3',
name: 'Nikita Gigir',
payment_amount : 100,
sku: 'ST004403030',
seq: '1'
}]
但我正在尝试通过以下方式提取数据。
[{
id: '1',
name: 'Maya Mahardhani',
total_amount : 150,
sku_1: 'ST001802027',
sku_2: 'ST000703044',
},
{
id: '2',
name: 'Tara Debu Batara',
total_amount : 100,
sku_1: 'ST005101001'
},
{
id: '3',
name: 'Nikita Gigir',
total_amount : 100,
sku_1: 'ST004403030'
}]
我尝试使用 JavaScript 的 reduce
函数。但是它会用旧的覆盖 prev 键。我的代码片段就是这样。我想我更接近解决。但仍在寻求帮助
orderResults.reduce((res, obj) => {
res[obj.id] = {
total_amount : (obj.id in res ? res[obj.id].total_amount : 0) + obj.payment_amount,
name : obj.name,
}
res[obj.id]['sku' + obj.seq]= obj.sku
return res;
},[])
谢谢
我认为这会完成您想要做的事情:
orderResults.reduce((res, obj, i) => {
const existingIdx = res.findIndex(r => r.id === obj.id)
if (existingIdx > -1) {
res[existingIdx] = {
...res[existingIdx],
total_amount : res[existingIdx].total_amount ? res[existingIdx].total_amount + obj.payment_amount : res[existingIdx].payment_amount + obj.payment_amount,
name : obj.name,
['sku_' + obj.seq]: obj.sku
}
} else {
res.push({
id: obj.id,
name: obj.name,
total_amount: obj.payment_amount,
['sku_' + obj.seq]: obj.sku
})
}
return res;
},[])
注意此行将保留原始对象并覆盖之后定义的任何重复键:
...res[existingIdx],
此外,当您的代码运行此行时:
res[obj.id] = {
它正在数组中设置一个特定的索引,我认为你不想这样做。您想要推送(如果尚未添加对象 ID),或者在创建具有相同 ID 的对象时覆盖原始插入点处的现有对象。
不要每次都创建一个新对象。
const result = Object.values(orderResults.reduce((res, obj) => {
res[obj.id] = res[obj.id] ||
{
id: obj.id,
total_amount : 0,
name : obj.name,
};
res[obj.id].total_amount += obj.total_amount;
res[obj.id]['sku' + obj.seq] = obj.sku;
return res;
},[]))
[{
id: '1',
name: 'Maya Mahardhani',
payment_amount: 100,
sku: 'ST001802027',
seq: '1'
},
{
id: '1',
name: 'Maya Mahardhani',
payment_amount: 50,
sku: 'ST000703044',
seq: '2'
},
{
id: '2',
name: 'Tara Debu Batara',
payment_amount: 100,
sku: 'ST005101001',
seq: '1'
},
{
id: '3',
name: 'Nikita Gigir',
payment_amount: 100,
sku: 'ST004403030',
seq: '1'
}].reduce((acc, current) => {
const { id, name, payment_amount, sku, seq } = current;
const previousRecord = acc[id];
if (typeof previousRecord === 'object') {
return {
...acc,
[id]: {
...previousRecord,
[`sku_${seq}`]: sku,
total_amount: previousRecord.total_amount + payment_amount
}
}
} else {
return {
...acc,
[id]: {
id,
name,
[`sku_${seq}`]: sku,
total_amount: payment_amount
}
}
}
}, {}) // returns an Object; use Object.values to convert to a list