繁体   English   中英

Javascript Map 减少对象的 Arrays 中的多个字段

[英]Javascript Map Reduce Multiple Fields in Arrays of Objects

我正在尝试总结多个 arrays 对象(键值对)。 我发现另一篇使用 map 减少 function 的帖子,但我不确定如何将其翻译为通过多个键返回。 当前的解决方案显示按月减少和映射,但我需要按月和销售人员减少和 map。 我的 HTML 索引中有 d3 下拉菜单,其中包含月份和销售人员,其中包括两个类别中的所有选项。

When a single salesperson and all months are selected the data_array looks like this:

data_array =  [{salesperson: 'Beth', month: 'Feb', 'value ly': 8, 'value plan': 10, 'value ty' : 14},
    {salesperson: 'Beth', month: 'Jan', 'value ly': 16, 'value plan': 18, 'value ty' : 20},
    {salesperson: 'Beth', month: 'Feb', 'value ly': 12, 'value plan': 15, 'value ty' : 18},
    { salesperson: 'Beth', month: 'Jan', 'value ly': 13, 'value plan': 21, 'value ty' : 25}]

When all salespersons and all months are selected the data_array looks like this:

data_array = [{salesperson: 'Joe', month: 'Jan', 'value ly': 10, 'value plan': 20, 'value ty' : 30},
{salesperson: 'Joe', month: 'Jan', 'value ly': 14, 'value plan': 18, 'value ty' : 22},  
{salesperson: 'Greg', month: 'Feb', 'value ly': 5, 'value plan': 10, 'value ty' : 12},
{ salesperson: 'Greg', month: 'Feb', 'value ly': 7, 'value plan': 9, 'value ty' : 5},
{salesperson: 'Joe', month: 'Feb', 'value ly': 12, 'value plan': 14, 'value ty' : 16},
{ salesperson: 'Joe', month: 'Feb', 'value ly': 15, 'value plan': 16, 'value ty' : 13},
{salesperson: 'Beth', month: 'Feb', 'value ly': 8, 'value plan': 10, 'value ty' : 14},
{salesperson: 'Beth', month: 'Jan', 'value ly': 16, 'value plan': 18, 'value ty' : 20},
{salesperson: 'Beth', month: 'Feb', 'value ly': 12, 'value plan': 15, 'value ty' : 18},
{ salesperson: 'Beth', month: 'Jan', 'value ly': 13, 'value plan': 21, 'value ty' : 25}]

使用 data_array 的第一个结果,我的代码运行如下:

 data_array =  [{salesperson: 'Beth', month: 'Feb', 'value ly': 8, 'value plan': 10, 'value ty' : 14},
        {salesperson: 'Beth', month: 'Jan', 'value ly': 16, 'value plan': 18, 'value ty' : 20},
        {salesperson: 'Beth', month: 'Feb', 'value ly': 12, 'value plan': 15, 'value ty' : 18},
        { salesperson: 'Beth', month: 'Jan', 'value ly': 13, 'value plan': 21, 'value ty' : 25}]
        
    let reduced_data_array = data_array.reduce((prev,next)=>{
       if (next.month in prev) {
             prev[next.month]['value ly'] += next['value ly'];
             prev[next.month]['value plan'] += next['value plan'];
             prev[next.month]['value ty'] += next['value ty'];
       } else {
             prev[next.month] = next;
       return prev;
    }, {});
        
let mapped_reduced_data = Object.keys(reduced_data_array).map(month => reduced_data_array[month]);

return mapped_reduced_data

选择单个销售员时,所有月份都以这种格式返回数据(例如:贝丝和所有月份):

在此处输入图像描述

我想更改我的 map 并在选择所有销售人员和所有月份(第二个数据集)时减少函数以返回以下内容:

在此处输入图像描述

TL;博士

您不需要mapreduce 只需一个简单的filter就可以完全满足您的需求。

data_array.filter(
  obj => LIST_OF_SALESPERSON.includes(obj.salesperson)) && LIST_OF_MONTHS.includes(obj.month)
);

为了测试这种行为,我使用您提供的数据创建了一个简单的示例。 只需点击“运行代码片段”:

 // Data const data_array = [{salesperson: 'Joe', month: 'Jan', 'value ly': 10, 'value plan': 20, 'value ty': 30}, {salesperson: 'Joe', month: 'Jan', 'value ly': 14, 'value plan': 18, 'value ty': 22}, {salesperson: 'Greg', month: 'Feb', 'value ly': 5, 'value plan': 10, 'value ty': 12}, { salesperson: 'Greg', month: 'Feb', 'value ly': 7, 'value plan': 9, 'value ty': 5}, {salesperson: 'Joe', month: 'Feb', 'value ly': 12, 'value plan': 14, 'value ty': 16}, { salesperson: 'Joe', month: 'Feb', 'value ly': 15, 'value plan': 16, 'value ty': 13}, {salesperson: 'Beth', month: 'Feb', 'value ly': 8, 'value plan': 10, 'value ty': 14}, {salesperson: 'Beth', month: 'Jan', 'value ly': 16, 'value plan': 18, 'value ty': 20}, {salesperson: 'Beth', month: 'Feb', 'value ly': 12, 'value plan': 15, 'value ty': 18}, { salesperson: 'Beth', month: 'Jan', 'value ly': 13, 'value plan': 21, 'value ty': 25}]; // Function containing the logic behind the filter function getDataByFilter (filters) { return data_array.filter( obj => (filters.salesperson.length == 0 || filters.salesperson.includes(obj.salesperson)) && (filters.month.length == 0 || filters.month.includes(obj.month)) ); } // Get all data here by passing to the function the desired filters var data_no_filter = getDataByFilter({ "salesperson": [], "month": [] }); var data_by_salesperson = getDataByFilter({ "salesperson": ["Greg", "Beth"], "month": [] }); var data_by_salesperson_and_month = getDataByFilter({ "salesperson": ["Greg", "Beth"], "month": ["Feb"] }); // Print to console the data we have previously filtered console.log("No filters: %o", data_no_filter); console.log("By SalesPerson: %o", data_by_salesperson); console.log("By SalesPerson and Month: %o", data_by_salesperson_and_month);

如何实施?

只需像示例中的那样传递给getDataByFilter function 和Object ,您将在其中添加从 select 获得的数据,然后您将收到过滤后的数据

在我发布此内容后搜索了几天后,我实际上找到了一个有效的答案:

    const reduce_data = data_array.reduce((result, d) => {
        let key = `${d.RSM}_${d.Month}`;
        result[key] = result[key] || {...d, 'value ly':0, 'value plan':0, 'value ty':0};
        result[key]['value ly'] += +d['value ly'];
        result[key]['value plan'] += +d['value plan'];
        result[key]['value ty'] += +d['value ty'];

        return result
    }, {});
    const data_result = Object.values(reduce_data);

暂无
暂无

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

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