最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Sum data from two array of objects - Stack Overflow

programmeradmin2浏览0评论

I have two array of objects, and I want to sum the object that have a same key (in this case, id), and if there is no match key, then just create a new one.. I'm sorry if I am not explaining it clearly, I am new to JavaScript/Array/Object thing...

var dataOne = [ { id:"1", total: 10, win: 5 }, { id:"2", total: 5, win: 1 }, { id:"3", total: 5, win: 2 } ]

and

var dataTwo = [ { id:"1", total: 5, win: 2 }, { id:"2", total: 2, win: 3 }, { id:"5", total: 5, win: 4 } ]

Expected result:

var binedData = [ { id:"1", total: 15, win: 7 }, { id:"2", total: 7, win: 4 }, { id:"3", total: 5, win: 2 }, { id:"5", total: 5, win: 4 } ]

I have tried to use the solution from Sum all data in array of objects into new array of objects but, apparently the type of data is kind of different

So, I tried to use this method from Javascript - Sum of two object with same properties

 function sumObjectsByKey(...objs) {
      for (var prop in n) {
        if (acc.hasOwnProperty(prop)) acc[prop] += n[prop];
        else acc[prop] = n[prop];
      }
      return acc;
    }

and

var binedData = sumObjectsByKey(dataOne, dataTwo);

But apparently, that method won't work for an array of objects. I get

{0: "0[object Object][object Object]", 1: "0[object Object][object Object]", 2: "0[object Object][object Object]"}

as a result.

I have two array of objects, and I want to sum the object that have a same key (in this case, id), and if there is no match key, then just create a new one.. I'm sorry if I am not explaining it clearly, I am new to JavaScript/Array/Object thing...

var dataOne = [ { id:"1", total: 10, win: 5 }, { id:"2", total: 5, win: 1 }, { id:"3", total: 5, win: 2 } ]

and

var dataTwo = [ { id:"1", total: 5, win: 2 }, { id:"2", total: 2, win: 3 }, { id:"5", total: 5, win: 4 } ]

Expected result:

var binedData = [ { id:"1", total: 15, win: 7 }, { id:"2", total: 7, win: 4 }, { id:"3", total: 5, win: 2 }, { id:"5", total: 5, win: 4 } ]

I have tried to use the solution from Sum all data in array of objects into new array of objects but, apparently the type of data is kind of different

So, I tried to use this method from Javascript - Sum of two object with same properties

 function sumObjectsByKey(...objs) {
      for (var prop in n) {
        if (acc.hasOwnProperty(prop)) acc[prop] += n[prop];
        else acc[prop] = n[prop];
      }
      return acc;
    }

and

var binedData = sumObjectsByKey(dataOne, dataTwo);

But apparently, that method won't work for an array of objects. I get

{0: "0[object Object][object Object]", 1: "0[object Object][object Object]", 2: "0[object Object][object Object]"}

as a result.

Share Improve this question asked Jun 9, 2019 at 17:00 MavysMavys 331 silver badge4 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

Combine both using rest params and Array.flat(). Reduce the items into a Map, while bining the current item, with the item that already exists in the Map. Convert the Map.values() iterator to an array with Array.from():

const sumObjectsByKey = (sumFn, ...arrs) => Array.from(
  arrs.flat() // bine the arrays
  .reduce((m, o) => // retuce the bined arrays to a Map
    m.set(o.id, // if add the item to the Map
      m.has(o.id) ? sumFn(m.get(o.id), o) : { ...o } // if the item exists in Map, sum the current item with the one in the Map. If not, add a clone of the current item to the Map
    )
  , new Map).values()
)

// utility function to sum to object values (without the id)
const sumItem = ({ id, ...a }, b) => ({
  id,
  ...Object.keys(a)
    .reduce((r, k) => ({ ...r, [k]: a[k] + b[k] }), {})
});

const dataOne = [ { id:"1", total: 10, win: 5 }, { id:"2", total: 5, win: 1 }, { id:"3", total: 5, win: 2 } ]
const dataTwo = [ { id:"1", total: 5, win: 2 }, { id:"2", total: 2, win: 3 }, { id:"5", total: 5, win: 4 } ]

const result = sumObjectsByKey(sumItem, dataOne, dataTwo)
  
console.log(result)

I'd suggest Array.reduce here. In the body of the reduction function, if the id isn't in the result accumulator, add it, then increment all of the values for each property in the object.

var dataOne = [ { id:"1", total: 10, win: 5 }, { id:"2", total: 5, win: 1 }, { id:"3", total: 5, win: 2 } ]
var dataTwo = [ { id:"1", total: 5, win: 2 }, { id:"2", total: 2, win: 3 }, { id:"5", total: 5, win: 4 } ]

var sumObjectsByKey = (...objs) => 
  Object.values(objs.reduce((a, e) => {
    a[e.id] = a[e.id] || {id: e.id};

    for (const k in e) {
      if (k !== "id") {
        a[e.id][k] = a[e.id][k] ? a[e.id][k] + e[k] : e[k];
      }
    }

    return a;
  }, {}))
;

console.log(sumObjectsByKey(...dataOne, ...dataTwo));

发布评论

评论列表(0)

  1. 暂无评论