Javascript根据条件对对象进行分组

Javascript根据条件对对象进行分组,javascript,Javascript,我有以下数据: var foo = [ {'MonthNo' : 03, 'CustomerTypeID' : 1 , 'TotalSales' : 45 }, {'MonthNo' : 03, 'CustomerTypeID' : 2 , 'TotalSales' : 64 }, {'MonthNo' : 03, 'CustomerTypeID' : 4 , 'TotalSales' : 89 }, {'MonthNo' : 03, 'CustomerTypeI

我有以下数据:

var foo = [
    {'MonthNo' : 03, 'CustomerTypeID' : 1 , 'TotalSales' : 45 },
    {'MonthNo' : 03, 'CustomerTypeID' : 2 , 'TotalSales' : 64 },
    {'MonthNo' : 03, 'CustomerTypeID' : 4 , 'TotalSales' : 89 },
    {'MonthNo' : 03, 'CustomerTypeID' : 5 , 'TotalSales' : 42 },
    {'MonthNo' : 04, 'CustomerTypeID' : 1 , 'TotalSales' : 66 },
    {'MonthNo' : 04, 'CustomerTypeID' : 2 , 'TotalSales' : 78 },
    {'MonthNo' : 04, 'CustomerTypeID' : 5 , 'TotalSales' : 20 },
    {'MonthNo' : 04, 'CustomerTypeID' : 6 , 'TotalSales' : 10 }
];
我想将其转换为以下内容

{'MonthNo' : 03, 'CustomerTypeID' : 1 , 'TotalSales' : 198 },
{'MonthNo' : 03, 'CustomerTypeID' : 5 , 'TotalSales' : 42 },
{'MonthNo' : 04, 'CustomerTypeID' : 1 , 'TotalSales' : 144 },
{'MonthNo' : 04, 'CustomerTypeID' : 5 , 'TotalSales' : 20 },
{'MonthNo' : 04, 'CustomerTypeID' : 6 , 'TotalSales' : 10 }
对于每个月,除了CustomerTypeID5和6之外,我想把总销售额加起来。 对于Ex:MonthNo 03,对于CustomerTypeID 1,2,4,其总销售价值总计为198。同样,对于MonthNo 04,CustomerTypeID 1和2的总销售价值总计为144

我试着使用reduce函数

var result = foo.reduce(function(obj,item){
    // code here
},{});
但是,我无法将它们分开以获得所需的结果。任何帮助都将不胜感激

answer={};
for(i=0;i<foo.length;i++){
elem=foo[i];
answer[elem["MonthNo"]]=answer[elem["MonthNo"]]||{};
answer[elem["MonthNo"]][elem["CustomerTypeId"]]=answer[elem["MonthNo"]][elem["CustomerTypeId"]]||0;
     answer[elem["MonthNo"]][elem["CustomerTypeId"]]+=elem["TotalSales"];
}
现在可以打印(或推送到阵列):


您可以检查特殊情况,并使用哈希表引用正确的对象进行计数

var foo=[{MonthNo:'03',CustomerTypeID:1,TotalSales:45},{MonthNo:'03',CustomerTypeID:2,TotalSales:64},{MonthNo:'03',CustomerTypeID:4,TotalSales:89},{MonthNo:'03',CustomerTypeID:5,TotalSales:42},{MonthNo:'04',CustomerTypeID:1,TotalSales:66},{MonthNo:'04',CustomerTypeID:2,TotalSales:78},{MonthNo:'04',CustomerTypeID:5,TotalSales:20},{MonthNo:'04',CustomerTypeID:6,TotalSales:10}],
结果=foo.reduce(函数(散列){
返回函数(r,a){
var cType=[5,6]。indexOf(a.CustomerTypeID)==-1?1:a.CustomerTypeID,
key=[a.MonthNo,cType].join(“|”);
如果(!哈希[键]){
hash[key]={MonthNo:a.MonthNo,CustomerTypeID:cType,TotalSales:0};
r、 push(散列[键]);
}
哈希[key].TotalSales+=a.TotalSales;
返回r;
}
}(Object.create(null)),[]);
console.log(结果);

.as console wrapper{max height:100%!important;top:0;}
您可以检查现有的数组monthno和customerTypeID,并相应地计算总销售额

检查以下代码段

var foo=[{
“MonthNo”:03,
“CustomerTypeID”:1,
“总销售额”:45
}, {
“MonthNo”:03,
“CustomerTypeID”:2,
“总销售额”:64
}, {
“MonthNo”:03,
“CustomerTypeID”:4,
“总销售额”:89
}, {
“MonthNo”:03,
“CustomerTypeID”:5,
“总销售额”:42
}, {
“蒙特诺”:04,
“CustomerTypeID”:1,
“总销售额”:66
}, {
“蒙特诺”:04,
“CustomerTypeID”:2,
“总销售额”:78
}, {
“蒙特诺”:04,
“CustomerTypeID”:5,
“总销售额”:20
}, {
“蒙特诺”:04,
“CustomerTypeID”:6,
“总销售额”:10
}];
var reducedfoo=foo.reduce(函数(上一个、当前、索引){
var索引=检查存在性(上一个,当前)
如果(索引>-1)
上一个[索引].TotalSales+=current.TotalSales;
其他的
前推(当前);
返回上一个;
}, []);
函数检查是否存在(上一个,当前){
var指数=-1;
Object.key(prev.forEach)(函数(项){
if(上一个[项目].MonthNo==curr.MonthNo&&curr.CustomerTypeID!=5&&curr.CustomerTypeID!=6)
索引=项目;
});
收益指数;
}

console.log(reducedfoo);
这可以帮助您按MonthNo对foo数组进行排序

var foo=[
{'MonthNo':03,'CustomerTypeID':1,'TotalSales':45},
{'MonthNo':03,'CustomerTypeID':2,'TotalSales':64},
{'MonthNo':03,'CustomerTypeID':4,'TotalSales':89},
{'MonthNo':03,'CustomerTypeID':5,'TotalSales':42},
{'MonthNo':04,'CustomerTypeID':1,'TotalSales':66},
{'MonthNo':04,'CustomerTypeID':2,'TotalSales':78},
{'MonthNo':04,'CustomerTypeID':5,'TotalSales':20},
{'MonthNo':04,'CustomerTypeID':6,'TotalSales':10}
];
var curMonth=-1,result=[],curObj;
对于(变量i=0;iconsole.log(result);
使用reduce的两步功能方法:

var groups = foo.reduce(function(groups,item){
  var newGroup;
  var groupId = item.MonthNo;
  if (item.CustomerTypeID === 5 || item.CustomerTypeID === 6) {
    groupId = groupId + '-' + item.CustomerTypeID;
  }
  if (!groups[groupId]) {
    groups[groupId] = [];
  }
  groups[groupId].push(item);
  return groups;
},{});

var result = Object.keys(groups).reduce(function(res, groupId) {
  var merged = groups[groupId].reduce(function(merged, item) { 
    if (!merged.MonthNo) {
        merged.MonthNo = item.MonthNo;
    }
    if (!merged.CustomerTypeID) {
        merged.CustomerTypeID = item.CustomerTypeID;
    }
    merged.TotalSales = merged.TotalSales + item.TotalSales;
    return merged;
  }, {TotalSales: 0});
  res.push(merged);
  return res;
}, []);

console.log(result);

注意:对于ES6,这看起来会更好。

@Rajesh它实际上在一行上可读性更强。@Scimonster Point接受,但请分两部分重新格式化,输入和输出您的结果缺少数组周围的括号。这不是
reduce
的好用法。只需使用普通循环,并创建使用
MonthNo的嵌套对象即可
CustomerTypeID
作为键,其值是累计销售额。请解释您的尝试。仅仅添加代码是不好的,您能将其制作成一个可执行的堆栈片段以便我们可以看到结果吗?我不知道这是如何将
TotalSales
值相加的。@Barmar:我在学校,在那里被一节课打断了…应该有效now@bikash一种不太优雅的方法是。尽管只是一个指针,但您应该尝试对输入进行排序。这将更加一致。您也可以尝试
A.CustomerTypeID>=5
,而不是签入数组。但是,是的,拥有数组将允许您配置值。
for(month in answer){
 for(id in answer[month]){
   console.log(month+" "+id+":"+answer[month][id];
 }}
var groups = foo.reduce(function(groups,item){
  var newGroup;
  var groupId = item.MonthNo;
  if (item.CustomerTypeID === 5 || item.CustomerTypeID === 6) {
    groupId = groupId + '-' + item.CustomerTypeID;
  }
  if (!groups[groupId]) {
    groups[groupId] = [];
  }
  groups[groupId].push(item);
  return groups;
},{});

var result = Object.keys(groups).reduce(function(res, groupId) {
  var merged = groups[groupId].reduce(function(merged, item) { 
    if (!merged.MonthNo) {
        merged.MonthNo = item.MonthNo;
    }
    if (!merged.CustomerTypeID) {
        merged.CustomerTypeID = item.CustomerTypeID;
    }
    merged.TotalSales = merged.TotalSales + item.TotalSales;
    return merged;
  }, {TotalSales: 0});
  res.push(merged);
  return res;
}, []);

console.log(result);