繁体   English   中英

使用.reduce函数进行某些计算并返回带有数组结果的对象

[英]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
    }
  ]
}

这正是我所追求的,但是当处理不同的days数组时,它遵循对象数组的相同结构。 我在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返回的对象格式与输入数组匹配,如

return {
    stats: nextStats,
};

您的数组如下所示:

const days = [{ stats: [...] }]

因此,当您的内部循环将.stats作为数组进行迭代时,它将正确运行。

您的第二个 reducer迭代具有以下结构的对象:

const days = [{ statistics: { breakdown: { byTurnover: [...] } }]

但是然后返回与该结构不匹配的对象:

return {
    stats: nextStats,
};

因此,reducer的第一个迭代将起作用,然后将运行第二个迭代,并且第一个参数pastDay将是上一次运行的返回值,它将没有您要查找的任何键。

一个快速而肮脏的解决方案就是在返回时匹配对象键的深度:

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 } },
    };
});

虽然这回答了问题,但您难以遵循所使用的逻辑。 根据您要完成的工作(代码尚不清楚),这可能不是理想的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM