0

I am trying to sum values from different objects. Each object has its ID, but the IDs can repeat in some objects. What I need to do now is sum the values from the objects that have the same ID.

Does someone have an idea for me? I tried to use mongoose aggregate, but with no success.

Let's suppose I have the objects below.

const array = [
  { _id: "123456", value: 30 },
  { _id: "123456789123456789", value: 12 },
  { _id: "123456", value: 25 },
];

I would need something that brings up the following result:

==>  id: 123456
     value: 55

==>  id: 123456789123456789
     value: 12
kelsny
  • 23,009
  • 3
  • 19
  • 48

3 Answers3

1

Reduce the array into a map. Conveniently, map.set returns the map, so it's just a one-liner.

const array = [{ _id: "123456", value: 30 }, { _id: "123456789123456789", value: 12 }, { _id: "123456", value: 25 }];

const sums = array.reduce((map, object) => map.set(object._id, map.get(object._id) ?? object.value), new Map());

console.log(sums.get("123456"));
console.log(sums.get("123456789123456789"));

// convert to normal object

const sumsAsNormalObject = Object.fromEntries([...sums.entries()]);

console.log(sumsAsNormalObject);

Confused about syntax? See nullish coalescing and spread syntax. You can also convert the map into a plain object if you wanted to.

kelsny
  • 23,009
  • 3
  • 19
  • 48
0

its impossible to have duplicate _id in mongodb, but you can change that to something like dataId, id or else

example:

[
  {
    _id: 1,
    id: 123456,
    value: 30
  },
  {
    _id: 2,
    id: 123456789123456789,
    value: 12
  },
  {
    _id: 3,
    id: 123456,
    value: 25
  }
]

then with wongo would be like:

db.collection.aggregate([
  {
    "$group": {
      "_id": "$id",
      "value": {
        "$sum": "$value"
      }
    }
  }
])

MONGO-PLAYGROUND

Note: if some data can be handle by resources/database, use it instead. otherwise, create a function to handle it.

Tobok Sitanggang
  • 607
  • 5
  • 15
0

For each object, it checks whether the "result" object already has a property with the same _id as the current object being looped over.

    const array = [
      { _id: "123456", value: 30 },
      { _id: "123456789123456789", value: 12 },
      { _id: "123456", value: 25 },
    ];
    
    const result = {};
    
    array.forEach(item => {
      if(result[item._id]) {
        result[item._id] += item.value;
      } else {
        result[item._id] = item.value;
      }
    });
    
    console.log(result);