1

It is possible to sum the values of an array if they are the same like this:

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

To return something like this:

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

Wihout losing the other parts of the array? (doing by hand is hard because I have more than 10 thousand duplicates like the example above, and the array have 600 thousand entries.

3 Answers 3

3

You could use map() to create new array and inside reduce() to group items objects by id and sum qty.

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)

Sign up to request clarification or add additional context in comments.

1 Comment

your result looks different than expected.
2

You could take the power of Map and render the result by using Array.from with a mapping function which builds new objects for 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; }

Comments

2

You can use the functions forEach and reduce

This approach mutates the original array

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

If you want to create a new array and keep the original data:

This approach uses the function map to create a new "cloned" array.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.