使用 .reduce 函数进行某些计算和 return 具有数组结果的对象
Using the .reduce function to made certain calculations and return an object with array results
所以我已经成功地获得了我想要的结果:
const days = [
{
date: '2016-12-13T00:00:00.000Z',
stats: [
{ name: 'Soft Drinks', sold: 34, },
{ name: 'Snacks', sold: 3, },
{ name: 'Coffee and warm drinks', sold: 26, },
],
},
{
date: '2016-12-14T00:00:00.000Z',
stats: [
{ name: 'Soft Drinks', sold: 34, },
{ name: 'Snacks', sold: 3, },
{ name: 'Coffee and warm drinks', sold: 26, },
],
},
];
const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.stats.map(function(stat) {
const oldSold = pastDay.stats.find(function (old) {
return old.name === stat.name;
});
const newSold = stat.sold + oldSold.sold;
stat.sold = newSold;
return stat;
});
return {
stats: nextStats,
};
});
console.log(newStats);
输出:
{
"stats": [
{
"name": "Soft Drinks",
"sold": 68
},
{
"name": "Snacks",
"sold": 6
},
{
"name": "Coffee and warm drinks",
"sold": 52
}
]
}
这正是我所追求的,但是在处理不同的日期数组时,它们遵循相同的对象数组结构。我在 pastDay
上收到未定义的错误任何人都可以帮助我发现问题吗?或者帮我找到 .reduce
的替代品
我遇到问题的数组:
const days = [
{
"_id":{
"_str":"f23f02994ab992437e423e24"
},
"date":"2016-12-13T00:00:00.000Z",
"statistics":{
"breakdown":{
"byTurnover":[
{
"name":"Soft Drinks",
"sold":34,
"percentage":31.14
},
{
"name":"Snacks",
"sold":3,
"percentage":2.65
},
{
"name":"Coffee and warm drinks",
"sold":26,
"percentage":21.54
},
{
"name":"Brandy",
"sold":2,
"percentage":2.75
},
{
"name":"Beer",
"sold":20,
"percentage":20.15
},
{
"name":"Mixed drinks Other",
"sold":21,
"percentage":21.77
}
],
}
},
"id":{
"_str":"f23f02994ab992437e423e24"
}
},
{
"_id":{
"_str":"b3d0ad7f314e33021739f70c"
},
"date":"2016-12-14T00:00:00.000Z",
"statistics":{
"breakdown":{
"byTurnover":[
{
"name":"Soft Drinks",
"sold":34,
"percentage":31.14
},
{
"name":"Snacks",
"sold":3,
"percentage":2.65
},
{
"name":"Coffee and warm drinks",
"sold":26,
"percentage":21.54
},
{
"name":"Brandy",
"sold":2,
"percentage":2.75
},
{
"name":"Beer",
"sold":20,
"percentage":20.15
},
{
"name":"Mixed drinks Other",
"sold":21,
"percentage":21.77
}
],
}
},
"id":{
"_str":"b3d0ad7f314e33021739f70c"
}
},
{
"_id":{
"_str":"e1906ce07ab811c74528e3cc"
},
"date":"2016-12-15T00:00:00.000Z",
"statistics":{
"breakdown":{
"byTurnover":[
{
"name":"Soft Drinks",
"sold":34,
"percentage":31.14
},
{
"name":"Snacks",
"sold":3,
"percentage":2.65
},
{
"name":"Coffee and warm drinks",
"sold":26,
"percentage":21.54
},
{
"name":"Brandy",
"sold":2,
"percentage":2.75
},
{
"name":"Beer",
"sold":20,
"percentage":20.15
},
{
"name":"Mixed drinks Other",
"sold":21,
"percentage":21.77
}
],
}
},
"id":{
"_str":"e1906ce07ab811c74528e3cc"
}
},
];
const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.statistics.breakdown.byTurnover.map(function(stat) {
const oldSold = pastDay.statistics.breakdown.byTurnover.find(function (old) {
return old.name === stat.name;
});
const newSold = stat.sold + oldSold.sold;
stat.sold = newSold;
return stat;
});
return {
stats: nextStats,
};
});
console.log(newStats);
输出:Uncaught TypeError: Cannot read property 'breakdown' of undefined
第二个数组的.reduce代码:
const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.statistics.breakdown.byTurnover.map(function(stat) {
const oldSold = pastDay.statistics.breakdown.byTurnover.find(function (old) {
return old.name === stat.name;
});
const newSold = stat.sold + oldSold.sold;
stat.sold = newSold;
return stat;
});
return {
stats: nextStats,
};
});
console.log(newStats);
您的第一个 reducer returning 一种与输入数组匹配的对象格式,如
return {
stats: nextStats,
};
你的数组看起来像:
const days = [{ stats: [...] }]
因此,当您的内部循环将 .stats
作为数组进行迭代时,它将正确地 运行.
您的 second reducer 正在迭代具有此结构的对象:
const days = [{ statistics: { breakdown: { byTurnover: [...] } }]
但是 return 一个对象与该结构不匹配:
return {
stats: nextStats,
};
因此 reducer 的第一次迭代将起作用,然后第二次迭代将 运行,第一个参数 pastDay
将是前一个 return 的值=38=],其中没有您要查找的任何键。
一个快速而肮脏的解决方案是在 returning:
时匹配对象键深度
const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.statistics.breakdown.byTurnover.map(function(stat) {
const oldSold = pastDay.statistics.breakdown.byTurnover.find(function (old) {
return old.name === stat.name;
});
const newSold = stat.sold + oldSold.sold;
stat.sold = newSold;
return stat;
});
return {
statistics: { breakdown: { byTurnover: nextStats } },
};
});
虽然这回答了问题,但您使用的逻辑很难理解。根据您要完成的目标(代码中并不清楚),这可能不是理想的实现方式。
所以我已经成功地获得了我想要的结果:
const days = [
{
date: '2016-12-13T00:00:00.000Z',
stats: [
{ name: 'Soft Drinks', sold: 34, },
{ name: 'Snacks', sold: 3, },
{ name: 'Coffee and warm drinks', sold: 26, },
],
},
{
date: '2016-12-14T00:00:00.000Z',
stats: [
{ name: 'Soft Drinks', sold: 34, },
{ name: 'Snacks', sold: 3, },
{ name: 'Coffee and warm drinks', sold: 26, },
],
},
];
const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.stats.map(function(stat) {
const oldSold = pastDay.stats.find(function (old) {
return old.name === stat.name;
});
const newSold = stat.sold + oldSold.sold;
stat.sold = newSold;
return stat;
});
return {
stats: nextStats,
};
});
console.log(newStats);
输出:
{
"stats": [
{
"name": "Soft Drinks",
"sold": 68
},
{
"name": "Snacks",
"sold": 6
},
{
"name": "Coffee and warm drinks",
"sold": 52
}
]
}
这正是我所追求的,但是在处理不同的日期数组时,它们遵循相同的对象数组结构。我在 pastDay
上收到未定义的错误任何人都可以帮助我发现问题吗?或者帮我找到 .reduce
我遇到问题的数组:
const days = [
{
"_id":{
"_str":"f23f02994ab992437e423e24"
},
"date":"2016-12-13T00:00:00.000Z",
"statistics":{
"breakdown":{
"byTurnover":[
{
"name":"Soft Drinks",
"sold":34,
"percentage":31.14
},
{
"name":"Snacks",
"sold":3,
"percentage":2.65
},
{
"name":"Coffee and warm drinks",
"sold":26,
"percentage":21.54
},
{
"name":"Brandy",
"sold":2,
"percentage":2.75
},
{
"name":"Beer",
"sold":20,
"percentage":20.15
},
{
"name":"Mixed drinks Other",
"sold":21,
"percentage":21.77
}
],
}
},
"id":{
"_str":"f23f02994ab992437e423e24"
}
},
{
"_id":{
"_str":"b3d0ad7f314e33021739f70c"
},
"date":"2016-12-14T00:00:00.000Z",
"statistics":{
"breakdown":{
"byTurnover":[
{
"name":"Soft Drinks",
"sold":34,
"percentage":31.14
},
{
"name":"Snacks",
"sold":3,
"percentage":2.65
},
{
"name":"Coffee and warm drinks",
"sold":26,
"percentage":21.54
},
{
"name":"Brandy",
"sold":2,
"percentage":2.75
},
{
"name":"Beer",
"sold":20,
"percentage":20.15
},
{
"name":"Mixed drinks Other",
"sold":21,
"percentage":21.77
}
],
}
},
"id":{
"_str":"b3d0ad7f314e33021739f70c"
}
},
{
"_id":{
"_str":"e1906ce07ab811c74528e3cc"
},
"date":"2016-12-15T00:00:00.000Z",
"statistics":{
"breakdown":{
"byTurnover":[
{
"name":"Soft Drinks",
"sold":34,
"percentage":31.14
},
{
"name":"Snacks",
"sold":3,
"percentage":2.65
},
{
"name":"Coffee and warm drinks",
"sold":26,
"percentage":21.54
},
{
"name":"Brandy",
"sold":2,
"percentage":2.75
},
{
"name":"Beer",
"sold":20,
"percentage":20.15
},
{
"name":"Mixed drinks Other",
"sold":21,
"percentage":21.77
}
],
}
},
"id":{
"_str":"e1906ce07ab811c74528e3cc"
}
},
];
const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.statistics.breakdown.byTurnover.map(function(stat) {
const oldSold = pastDay.statistics.breakdown.byTurnover.find(function (old) {
return old.name === stat.name;
});
const newSold = stat.sold + oldSold.sold;
stat.sold = newSold;
return stat;
});
return {
stats: nextStats,
};
});
console.log(newStats);
输出:Uncaught TypeError: Cannot read property 'breakdown' of undefined
第二个数组的.reduce代码:
const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.statistics.breakdown.byTurnover.map(function(stat) {
const oldSold = pastDay.statistics.breakdown.byTurnover.find(function (old) {
return old.name === stat.name;
});
const newSold = stat.sold + oldSold.sold;
stat.sold = newSold;
return stat;
});
return {
stats: nextStats,
};
});
console.log(newStats);
您的第一个 reducer returning 一种与输入数组匹配的对象格式,如
return {
stats: nextStats,
};
你的数组看起来像:
const days = [{ stats: [...] }]
因此,当您的内部循环将 .stats
作为数组进行迭代时,它将正确地 运行.
您的 second reducer 正在迭代具有此结构的对象:
const days = [{ statistics: { breakdown: { byTurnover: [...] } }]
但是 return 一个对象与该结构不匹配:
return {
stats: nextStats,
};
因此 reducer 的第一次迭代将起作用,然后第二次迭代将 运行,第一个参数 pastDay
将是前一个 return 的值=38=],其中没有您要查找的任何键。
一个快速而肮脏的解决方案是在 returning:
时匹配对象键深度const newStats = days.reduce(function (pastDay, currentDay) {
const nextStats = currentDay.statistics.breakdown.byTurnover.map(function(stat) {
const oldSold = pastDay.statistics.breakdown.byTurnover.find(function (old) {
return old.name === stat.name;
});
const newSold = stat.sold + oldSold.sold;
stat.sold = newSold;
return stat;
});
return {
statistics: { breakdown: { byTurnover: nextStats } },
};
});
虽然这回答了问题,但您使用的逻辑很难理解。根据您要完成的目标(代码中并不清楚),这可能不是理想的实现方式。