如何对数组中的相同对象求和

时间:2018-03-18 18:33:48

标签: javascript arrays sorting object

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

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},
    ],
  }]

没有丢失阵列的其他部分? (手工操作很难,因为我有超过1万个重复项,如上例所示,数组有60万个条目。

3 个答案:

答案 0 :(得分:3)

您可以使用map()创建新数组,并使用id和sum qty在reduce()内部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)




答案 1 :(得分:2)

您可以使用 forEach reduce

这些功能

此方法会改变原始数组

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; }

答案 2 :(得分: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; }