如何通过特定键合并数组中的项目?

时间:2016-09-06 19:37:25

标签: javascript arrays lodash

我有一个具有多个属性的JavaScript对象,这些属性的值是一个项目数组(type,count,senderUserName)。

我想组合这些具有相同类型的数组中的项目,同时保留它们最初对应的键。

以下是我的数组对象示例:

{C.J :[
  {"type":"call","count":2,"senderUserName":"C.J.Rosati"},   
  {"type":"email","count":0,"senderUserName":"C.J.Rosati"},
  {"type":"sms","count":1,"senderUserName":"C.J.Rosati"},
  {"type":"sms","count":0,"senderUserName":"C.J.Rosati"},
  {"type":"email","count":6,"senderUserName":"C.J.Rosati"}
],
Will :[
  {"type":"call","count":2,"senderUserName":"Will"},   
  {"type":"email","count":1,"senderUserName":"Will"},
  {"type":"sms","count":0,"senderUserName":"Will"},
  {"type":"call","count":1,"senderUserName":"Will"},
  {"type":"call","count":1,"senderUserName":"Will"},
]}

我想要的结果是:

{C.J :[
  {"type":"call","count":2,"senderUserName":"C.J.Rosati"},   
  {"type":"email","count":6,"senderUserName":"C.J.Rosati"},
  {"type":"sms","count":1,"senderUserName":"C.J.Rosati"}
],
Will :[
  {"type":"call","count":4,"senderUserName":"Will"},   
  {"type":"email","count":1,"senderUserName":"Will"},
  {"type":"sms","count":0,"senderUserName":"Will"},
]}

我一直在玩lodash方法来获得我的结果,但没有任何运气。我想我可能必须使用_.map_.reduce的组合,但不知道如何正确组合它们。

3 个答案:

答案 0 :(得分:5)

您可以使用纯JavaScript中的reduce()forEach()执行此操作。

var data = {'C.J' :[
  {"type":"call","count":2,"senderUserName":"C.J.Rosati"},   
  {"type":"email","count":0,"senderUserName":"C.J.Rosati"},
  {"type":"sms","count":1,"senderUserName":"C.J.Rosati"},
  {"type":"sms","count":0,"senderUserName":"C.J.Rosati"},
  {"type":"email","count":6,"senderUserName":"C.J.Rosati"}
],
'Will' :[
  {"type":"call","count":2,"senderUserName":"Will"},   
  {"type":"email","count":1,"senderUserName":"Will"},
  {"type":"sms","count":0,"senderUserName":"Will"},
  {"type":"call","count":1,"senderUserName":"Will"},
  {"type":"call","count":1,"senderUserName":"Will"},
]}
  
result = Object.keys(data).reduce(function(r, e) {
  var ar = [];
  data[e].forEach(function(a) {
    if (!this[a.type]) {
      this[a.type] = a;
      ar.push(this[a.type])
    } else {
      this[a.type].count += a.count;
    }
  }, {})
  r[e] = ar;
  return r;
}, {})

console.log(result)

答案 1 :(得分:0)

当然,也就是说,如果您有可用的ES6,并且不想在旧版浏览器中运行此客户端。

如果您使用lodash - 您可以执行以下操作:

var data = {"C.J" :[
{"type":"call","count":2,"senderUserName":"C.J.Rosati"},   
{"type":"email","count":0,"senderUserName":"C.J.Rosati"},
{"type":"sms","count":1,"senderUserName":"C.J.Rosati"},
{"type":"sms","count":0,"senderUserName":"C.J.Rosati"},
{"type":"email","count":6,"senderUserName":"C.J.Rosati"}
],
"Will" :[
{"type":"call","count":2,"senderUserName":"Will"},   
{"type":"email","count":1,"senderUserName":"Will"},
{"type":"sms","count":0,"senderUserName":"Will"},
{"type":"call","count":1,"senderUserName":"Will"},
{"type":"call","count":1,"senderUserName":"Will"},
]}

var combined_data = _.map(data, function(element, key){
  var collapsed_element = [];
  var element_type_hash = {};
  _.each(element, function(record){
    if(element_type_hash[record.type] !== undefined){
      element_type_hash[record.type].count += record.count;
    }   else
    {
      element_type_hash[record.type] = record;
    }
  });
  _.each(element_type_hash, function(element_obj){
    collapsed_element.push(element_obj);
  });

  return collapsed_element;
});

console.log(JSON.stringify(combined_data));

https://jsfiddle.net/oumba4p5/1/

答案 2 :(得分:0)

您可以使用_.transform()将密钥收集到字典中,并使用_.values()提取组合值:

var data = {
  'C.J' :[
    {"type":"call","count":2,"senderUserName":"C.J.Rosati"},   
    {"type":"email","count":0,"senderUserName":"C.J.Rosati"},
    {"type":"sms","count":1,"senderUserName":"C.J.Rosati"},
    {"type":"sms","count":0,"senderUserName":"C.J.Rosati"},
    {"type":"email","count":6,"senderUserName":"C.J.Rosati"}
  ],
  'Will' :[
    {"type":"call","count":2,"senderUserName":"Will"},   
    {"type":"email","count":1,"senderUserName":"Will"},
    {"type":"sms","count":0,"senderUserName":"Will"},
    {"type":"call","count":1,"senderUserName":"Will"},
    {"type":"call","count":1,"senderUserName":"Will"},
  ]
};

var result = _.transform(data, function(result, value, key) { // transform the original object
  result[key] = _(value)
  .transform(function(merged, obj) { // transform the array of objects
    if(merged[obj.type]) { // if the type key already exists
      merged[obj.type].count += obj.count; // add to count
    } else { // if not
     merged[obj.type] = obj; // the obj will be used for the type property
    }
  })
  .values() // take just the values
  .value();
});

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>