在数组中组合类似的对象

Posted

技术标签:

【中文标题】在数组中组合类似的对象【英文标题】:Combine Like Objects Within Array 【发布时间】:2016-04-23 01:15:32 【问题描述】:

我正在根据一系列订单生成税务报告。本质上我需要转换以下数组:

    [
  
    "rate": 6.75,
    "code": "US-NC-Guilford-27409",
    "grand": 39.981625,
    "tax": 2.02
  ,
  
    "rate": 7.5,
    "code": "US-NC-Orange-27516",
    "grand": 186.25,
    "tax": 11.25
  ,
  
    "rate": 7.5,
    "code": "US-NC-Orange-27516",
    "grand": 29.19625,
    "tax": 1.5
  
]

到每个类“code”的单独数组中,其中类“codes”可以等于任何内容,并且可以具有该类型的任意数量。所以它看起来像这样:

[  
   US-NC-Guilford-27409:[  
        
         "rate":6.75,
         "code":"US-NC-Guilford-27409",
         "grand":39.981625,
         "tax":2.02
      
   ],
   US-NC-Orange-27516:[  
        
         "rate":7.5,
         "code":"US-NC-Orange-27516",
         "grand":186.25,
         "tax":11.25
      ,
        
         "rate":7.5,
         "code":"US-NC-Orange-27516",
         "grand":29.19625,
         "tax":1.5
      
   ]
]

但我对格式化分离数据的其他方式完全持开放态度,但在生成报告时,我们必须提供每个税类的订单日志。

那么您将如何使用 javascript(Node)创建该输出?

【问题讨论】:

这不是您希望实现的有效结构。也许您的意思是结果是一个对象,而不是一个数组? 你尝试了什么?出了什么问题? 【参考方案1】:

不需要图书馆,Array.prototype.reduce 可以完成这项工作:

var data =     [
  
    "rate": 6.75,
    "code": "US-NC-Guilford-27409",
    "grand": 39.981625,
    "tax": 2.02
  ,
  
    "rate": 7.5,
    "code": "US-NC-Orange-27516",
    "grand": 186.25,
    "tax": 11.25
  ,
  
    "rate": 7.5,
    "code": "US-NC-Orange-27516",
    "grand": 29.19625,
    "tax": 1.5
  
]

var codes = data.reduce(function(acc, obj) 
    if (!acc.hasOwnProperty(obj.code)) acc[obj.code] = [];
    acc[obj.code].push(obj);
    return acc;
, );

document.write(JSON.stringify(codes));

编辑

根据 Xotic750 的建议,hasOwnProperty 测试可以简化为:

var codes = data.reduce(function(acc, obj) 
    if (!acc[obj.code]) acc[obj.code] = [];
    acc[obj.code].push(obj);
    return acc;
, Object.create(null));

可以进一步压缩为:

var codes = data.reduce(function(acc, obj) 
      return (acc[obj.code] || (acc[obj.code] = [])) && acc[obj.code].push(obj) && acc;
, Object.create(null));

虽然对于可维护的代码,我不建议这样做。如果你喜欢 ES6 箭头函数,那么:

var codes = data.reduce((acc, obj) => (acc[obj.code] || (acc[obj.code] = [])) && acc[obj.code].push(obj) && acc, Object.create(null));

完成了这项工作,但被严重混淆了。

【讨论】:

由于它是 node 并且可能符合 ES5,因此使用 Object.create(null) 而不是 可能更安全,以避免任何可能的冲突。 +1 @Xotic750 — 不知道更安全,但它会消除对 hasOwnProperty 的需要。 “更安全”可能不是最好的描述词,但你明白了我的意思;)【参考方案2】:

这看起来很适合 lodash _.groupBy() (see doc)

var processed = _.groupBy(original, 'code');

【讨论】:

完美就是我想要的! Unless a tag for a framework or library is also included, a pure JavaScript answer is expected for questions with the [tag:JavaScript] tag. 即使特别提到了节点?没有人写纯 NodeJS。 我看不出node 标签与它有什么关系。当然人们用纯 Javascript 编写它,你认为这样的库和框架是如何存在的? 我不明白反对意见。我认为这个答案非常有用。如果有人想在不使用任何库的情况下继续编写代码,那对我来说很好,但是,为什么要重新发明***呢?除非原始发帖人明确要求使用纯 JavaScript 并排除任何库,否则我相信这个答案可以解决问题,并提示可能用于解决类似问题的非常有用的库

以上是关于在数组中组合类似的对象的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 Javascript 中使用类似数组的对象?

在 Hive 中,如何组合多个表以生成包含对象数组的单行?

根据两个属性的唯一组合拆分对象数组

将数组拆分为包含唯一对象组合的最小子数组

如何组合 2 个对象并在其中合并数组 [重复]

基于嵌套数组重新组合对象数组