Naveen Paul
Naveen Paul

Reputation: 454

Merge two arrays of objects while summing for a particular key

I have two arrays

array1 = [ {_id: { month: 9, year: 2015 },
    count: 1,
    sampleDate: Tue Sep 22 2015 20:04:46 GMT+0530 (IST),
    interactions: [ [Object] ],
    interactionsBySelf: 0,
    interactionsByTeam: 1 },
  { _id: { month: 10, year: 2015 },
    count: 5,
    sampleDate: Thu Oct 01 2015 18:08:24 GMT+0530 (IST),
    interactions: [ [Object], [Object], [Object], [Object], [Object] ],
    interactionsBySelf: 0,
    interactionsByTeam: 5 },
  { _id: { month: 11, year: 2015 }]

and

array2 = [ {_id: { month: 9, year: 2015 },
    count: 3,
    sampleDate: Tue Sep 22 2015 20:04:46 GMT+0530 (IST),
    interactions: [ [Object],[Object],[Object] ],
    interactionsBySelf: 0,
    interactionsByTeam: 1 },
  { _id: { month: 10, year: 2015 },
    count: 7,
    sampleDate: Thu Oct 01 2015 18:08:24 GMT+0530 (IST),
    interactions: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
    interactionsBySelf: 0,
    interactionsByTeam: 5 },
  { _id: { month: 11, year: 2015 }]

How do I merge these two arrays such that the resulting array is Where the count and interactionsByteam is added up and the interactions merge. The _id and sampleDate remain the same

arrayResult = [{ _id: { month: 9, year: 2015 },
    count: 4,
    sampleDate: Tue Sep 22 2015 20:04:46 GMT+0530 (IST),
    interactions: [ [Object],[Object],[Object],[Object] ],
    interactionsBySelf: 0,
    interactionsByTeam: 4 },
  { _id: { month: 10, year: 2015 },
    count: 12,
    sampleDate: Thu Oct 01 2015 18:08:24 GMT+0530 (IST),
    interactions: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ],
    interactionsBySelf: 0,
    interactionsByTeam: 12 },
  { _id: { month: 11, year: 2015 }]

Upvotes: 0

Views: 86

Answers (3)

georg
georg

Reputation: 214969

With underscore:

g = _.groupBy(
    _.union(array1, array2),
    e => e._id.month + '/' + e._id.year
);

r = _.map(g, arrays => _.reduce(arrays, (x, y) => {
        x.count += y.count;
        x.interactions = x.interactions.concat(y.interactions);
        x.interactionsByTeam += y.interactionsByTeam;
        return x;
    })
)

Basically

  • concat both arrays
  • group sub-arrays with equal keys together
  • for each group, iterate sub-arrays and compute the totals object

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386620

This is a proposal for merging and counting with a temporary object and Array#forEach().

var array1 = [{ _id: { month: 9, year: 2015 }, count: 1, sampleDate: 'Tue Sep 22 2015 20:04:46 GMT+0530 (IST)', interactions: ['[Object1]'], interactionsBySelf: 0, interactionsByTeam: 1 }, { _id: { month: 10, year: 2015 }, count: 5, sampleDate: 'Thu Oct 01 2015 18:08:24 GMT+0530 (IST)', interactions: ['[Object2], [Object], [Object], [Object], [Object]'], interactionsBySelf: 0, interactionsByTeam: 5 }, { _id: { month: 11, year: 2015 } }],
    array2 = [{ _id: { month: 9, year: 2015 }, count: 3, sampleDate: 'Tue Sep 22 2015 20:04:46 GMT+0530 (IST)', interactions: ['[Object3],[Object],[Object]'], interactionsBySelf: 0, interactionsByTeam: 1 }, { _id: { month: 10, year: 2015 }, count: 7, sampleDate: 'Thu Oct 01 2015 18:08:24 GMT+0530 (IST)', interactions: ['[Object4], [Object], [Object], [Object], [Object], [Object], [Object]'], interactionsBySelf: 0, interactionsByTeam: 5 }, { _id: { month: 11, year: 2015 } }],
    result = function (array) {
        var o = {}, r = [];
        array.forEach(function (a) {
            var k = a._id.year + '|' + a._id.month;
            if (!(k in o)) {
                o[k] = {
                    _id: a._id,
                    count: 0,
                    sampleDate: a.sampleDate,
                    interactions: [],
                    interactionsBySelf: a.interactionsBySelf,
                    interactionsByTeam: 0
                };
                r.push(o[k]);
            }
            o[k].count += a.count;
            o[k].interactions = o[k].interactions.concat(a.interactions);
            o[k].interactionsByTeam += a.interactionsByTeam;
        });
        return r;
    }(array1.concat(array2));

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Upvotes: 1

bigOmega  ツ
bigOmega ツ

Reputation: 371

assuming both array are of same size,

arrayResult = array1.map((obj, i) => (
  {
    _id: obj._id,
    sampleDate: obj.sampleDate,
    interactionsBySelf: obj.interactionsBySelf,
    interactionsByTeam: obj.interactionsByTeam + array2[i].interactionsByTeam,
    interactions: obj.interactions.concat(array2[i].interactions),
  }
)

Upvotes: 0

Related Questions