简体   繁体   English

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

[英]Using the .reduce function to made certain calculations and return an object with array results

So I've successfully managed to get the results I'm after: 因此,我成功地获得了所追求的结果:

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

Outputs: 输出:

{
  "stats": [
    {
      "name": "Soft Drinks",
      "sold": 68
    },
    {
      "name": "Snacks",
      "sold": 6
    },
    {
      "name": "Coffee and warm drinks",
      "sold": 52
    }
  ]
}

Which is exactly what I'm after, however when dealing with a different days array, that follow the same structure of array of objects. 这正是我所追求的,但是当处理不同的days数组时,它遵循对象数组的相同结构。 I'm getting an undefined error on pastDay anyone can help me spot the problem? 我在pastDay上收到未定义的错误,有人可以帮助我发现问题吗? or help me find alternative to .reduce 或帮助我找到.reduce替代方法

The array I'm having trouble with: 我遇到麻烦的数组:

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

Outputs: Uncaught TypeError: Cannot read property 'breakdown' of undefined 输出: Uncaught TypeError: Cannot read property 'breakdown' of undefined

The .reduce code for the second array: 第二个数组的.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);

Your first reducer is returning an object format that matches the input array, as in 您的第一个 reducer返回的对象格式与输入数组匹配,如

return {
    stats: nextStats,
};

And your array looks like: 您的数组如下所示:

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

So when your inner loop iterates over .stats as an array, it will correctly run. 因此,当您的内部循环将.stats作为数组进行迭代时,它将正确运行。

Your second reducer is iterating over an object with this structure: 您的第二个 reducer迭代具有以下结构的对象:

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

But then returns an object not matching that structure: 但是然后返回与该结构不匹配的对象:

return {
    stats: nextStats,
};

So the first iteration of the reducer will work, then the second iteration will run, and the first argument, pastDay , will be the return value of the previous run, which won't have any of the keys you're looking up. 因此,reducer的第一个迭代将起作用,然后将运行第二个迭代,并且第一个参数pastDay将是上一次运行的返回值,它将没有您要查找的任何键。

A quick and dirty solution is just to match the object key depth when 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 } },
    };
});

While this answers the question, the logic you're using is hard to follow. 虽然这回答了问题,但您难以遵循所使用的逻辑。 Depending on what you're trying to accomplish, which is unclear from the code, this may not be an ideal way to do it. 根据您要完成的工作(代码尚不清楚),这可能不是理想的方法。

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

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