繁体   English   中英

功能性 Javascript 映射/减少准备报告数据

[英]Functional Javascript map/reduce in preparing report data

我正在努力理解如何正确使用Array.reduce()来组合汇总/报告数据(即分组计数)。 我通常通过使用forEach循环数据并构建对象来手动执行此操作,但我觉得链接 map 和 reduce 必须是一种更优雅、更实用的方法; 我只是不知道如何正确地做到这一点。

这是我的实验让我受益的地方:

const articleData = [
    {newsSource: "AP", title: "Some article.", category: "World"},
    {newsSource: "BBC", title: "Some article.", category: "Politics"},
    {newsSource: "CBS", title: "Some article.", category: "Sports"},
    {newsSource: "CNN", title: "Some article.", category: "Finance"},
    {newsSource: "CNN", title: "Another article.", category: "Politics"},
    {newsSource: "NBC", title: "Some article.", category: "Politics"},
    {newsSource: "NBC", title: "Another article.", category: "Finance"},
    {newsSource: "Reuters", title: "Some article.", category: "World"},
    {newsSource: "Reuters", title: "Another article.", category: "Politics"},
    {newsSource: "Reuters", title: "Yet another article.", category: "Finance"}
];

// I want to set reportData to be the result of the chained map/reduce
// ...not declare it here and assemble it within the functions below
let reportData = {};

articleData.map((item, index) => {
    if (item.newsSource) return item.newsSource;
})
.reduce((acc, newsSource) => {

    if (!reportData[newsSource]) {
        reportData[newsSource] = 1;
    } else {
        reportData[newsSource] = reportData[newsSource] + 1;
    }

    return (acc, reportData);

});

console.log(reportData);
// Expected output:
// { AP: 1, BBC: 1, CBS: 1, CNN: 2, NBC: 2, Reuters: 3 }

这里有很多问题。 (其中最重要的是它跳过了第一个数据元素!我想我明白为什么,但我不知道如何修复它。)但最重要的是,我想了解如何构建我的reduce函数,所以我'我没有更改其中的reportData ,而是返回“预期输出”下显示的正确结构化数据。

减少平面阵列对我来说很清楚,但是一旦我处理超出该深度的任何结构,我就会感到困惑。

您可以直接在articleData上使用Array.reduce

reportData = articleData.reduce(function(c, a) {
  c[a.newsSource] = (c[a.newsSource] || 0) + 1;
  return c;
}, {});

console.log(reportData);

请注意,正如@CertainPerformance 在他们的评论中指出的那样,您需要传递一个初始值来reduce否则数组中的第一个值将用作初始值并且不包含在迭代中。

 const articleData = [{ newsSource: "AP", title: "Some article.", category: "World" }, { newsSource: "BBC", title: "Some article.", category: "Politics" }, { newsSource: "CBS", title: "Some article.", category: "Sports" }, { newsSource: "CNN", title: "Some article.", category: "Finance" }, { newsSource: "CNN", title: "Another article.", category: "Politics" }, { newsSource: "NBC", title: "Some article.", category: "Politics" }, { newsSource: "NBC", title: "Another article.", category: "Finance" }, { newsSource: "Reuters", title: "Some article.", category: "World" }, { newsSource: "Reuters", title: "Another article.", category: "Politics" }, { newsSource: "Reuters", title: "Yet another article.", category: "Finance" } ]; reportData = articleData.reduce(function(c, a) { c[a.newsSource] = (c[a.newsSource] || 0) + 1; return c; }, {}); console.log(reportData);

您可以通过第一个值在reduce方法的2nd param中进行累加。 您可以在callback函数中跳过值或manipulate值。

 const articleData = [ { newsSource: "AP", title: "Some article.", category: "World" }, { newsSource: "BBC", title: "Some article.", category: "Politics" }, { newsSource: "CBS", title: "Some article.", category: "Sports" }, { newsSource: "CNN", title: "Some article.", category: "Finance" }, { newsSource: "CNN", title: "Another article.", category: "Politics" }, { newsSource: "NBC", title: "Some article.", category: "Politics" }, { newsSource: "NBC", title: "Another article.", category: "Finance" }, { newsSource: "Reuters", title: "Some article.", category: "World" }, { newsSource: "Reuters", title: "Another article.", category: "Politics" }, { newsSource: "Reuters", title: "Yet another article.", category: "Finance" } ]; const reportData = articleData.reduce((acc, { newsSource }) => { if (!acc[newsSource]) acc[newsSource] = 0; acc[newsSource] += 1; return acc; }, {}); console.log(reportData);

暂无
暂无

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

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