【问题标题】:How to sum the same objects in array如何对数组中的相同对象求和
【发布时间】:2018-08-27 08:03:37
【问题描述】:

如果数组的值相同,则可以对它们求和:

var COLLECTION = [
  {
    "coords":[1335,2525],
    "items":[
      {id: "boletus",qty: 1},
      {id: "lepiota",qty: 3},
      {id: "boletus",qty: 2},
      {id: "lepiota",qty: 4},
      {id: "carbonite",qty: 4},
    ],
  },
  {
    "coords":[1532,2889],
    "items":[
      {id: "boletus",qty: 2},
      {id: "lepiota",qty: 6},
      {id: "boletus",qty: 1},
      {id: "lepiota",qty: 4},
      {id: "chamomile",qty: 4},
    ],
  }]

要返回这样的内容:

var COLLECTION = [
  {
    "coords":[1335,2525],
    "items":[
      {id: "boletus",qty: 3},
      {id: "lepiota",qty: 7},
      {id: "carbonite",qty: 4},
    ],
  },
  {
    "coords":[1532,2889],
    "items":[
      {id: "boletus",qty: 3},
      {id: "lepiota",qty: 10},
      {id: "chamomile",qty: 4},
    ],
  }]

不会丢失数组的其他部分? (手工操作很困难,因为像上面的例子一样,我有超过 10,000 个重复项,而数组有 600,000 个条目。

【问题讨论】:

    标签: javascript arrays sorting object


    【解决方案1】:

    您可以使用map() 创建新数组并在reduce() 内部按id 和sum qty 对items 对象进行分组。

    var data = [{"coords":[1335,2525],"items":[{"id":"boletus","qty":1},{"id":"lepiota","qty":3},{"id":"boletus","qty":2},{"id":"lepiota","qty":4},{"id":"carbonite","qty":4}]},{"coords":[1532,2889],"items":[{"id":"boletus","qty":2},{"id":"lepiota","qty":6},{"id":"boletus","qty":1},{"id":"lepiota","qty":4},{"id":"chamomile","qty":4}]}]
      
    const result = data.map(function({coords, items}) {
      return {coords, items: Object.values(items.reduce(function(r, e) {
        if(!r[e.id]) r[e.id] = Object.assign({}, e)
        else r[e.id].qty += e.qty
        return r;
      }, {}))}
    })  
    
    console.log(result)

    【讨论】:

    • 您的结果看起来与预期不同。
    【解决方案2】:

    您可以利用Map 的强大功能并通过使用Array.from 和为items 构建新对象的映射函数来呈现结果。

    var COLLECTION = [{ coords: [1335, 2525], items: [{ id: "boletus", qty: 1 }, { id: "lepiota", qty: 3 }, { id: "boletus", qty: 2 }, { id: "lepiota", qty: 4 }, { id: "carbonite", qty: 4 }], }, { coords: [1532, 2889], items: [{ id: "boletus", qty: 2 }, { id: "lepiota", qty: 6 }, { id: "boletus", qty: 1 }, { id: "lepiota", qty: 4 }, { id: "chamomile", qty: 4 }] }];
    
    COLLECTION.forEach(o => {
        var map = new Map;
        o.items.forEach(({ id, qty }) => map.set(id, (map.get(id) || 0) + qty));
        o.items = Array.from(map, ([id, qty]) => ({ id, qty }));
    });
    
    console.log(COLLECTION);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

      【解决方案3】:

      您可以使用函数forEachreduce

      这种方法会改变原始数组

      var COLLECTION = [  {    "coords":[1335,2525],    "items":[      {id: "boletus",qty: 1},      {id: "lepiota",qty: 3},      {id: "boletus",qty: 2},      {id: "lepiota",qty: 4},      {id: "carbonite",qty: 4},    ],  },  {    "coords":[1532,2889],    "items":[      {id: "boletus",qty: 2},      {id: "lepiota",qty: 6},      {id: "boletus",qty: 1},      {id: "lepiota",qty: 4},      {id: "chamomile",qty: 4},    ],  }];
        
      COLLECTION.forEach((o) => {
        o.items = Object.values(o.items.reduce((a, c) => {
          (a[c.id] || (a[c.id] = {id: c.id, qty: 0})).qty += c.qty;
          return a;
        }, {}));
      });
      
      console.log(COLLECTION);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      如果要创建新数组并保留原始数据:

      这种方法使用函数 map 来创建一个新的“克隆”数组。

      var COLLECTION = [  {    "coords":[1335,2525],    "items":[      {id: "boletus",qty: 1},      {id: "lepiota",qty: 3},      {id: "boletus",qty: 2},      {id: "lepiota",qty: 4},      {id: "carbonite",qty: 4},    ],  },  {    "coords":[1532,2889],    "items":[      {id: "boletus",qty: 2},      {id: "lepiota",qty: 6},      {id: "boletus",qty: 1},      {id: "lepiota",qty: 4},      {id: "chamomile",qty: 4},    ] }],
          result = COLLECTION.map(o => o);
      
      result.forEach((o) => {
        o.items = Object.values(o.items.reduce((a, c) => {
          (a[c.id] || (a[c.id] = {id: c.id, qty: 0})).qty += c.qty;
          return a;
        }, {}));
      });
      
      console.log(result);
      .as-console-wrapper { max-height: 100% !important; top: 0; }

      【讨论】:

        猜你喜欢
        • 2020-10-25
        • 2014-08-18
        • 2013-10-14
        • 2018-08-17
        • 1970-01-01
        • 2015-06-29
        • 2021-10-09
        • 1970-01-01
        相关资源
        最近更新 更多