Merge objects with the same id but sum values of the objects

夙愿已清 提交于 2019-12-11 05:26:11

问题


I want to reduce my array of objects by comparing previous and current object from the array, if the id of previous object is different then current object, then I write the previous object to my result list and override it with the current object else I sum the values of both objects. In the end it should be a reduced array, no duplicates.

I have data like this:

[{
    Clicks: 210,
    Company: "A",
    _id: { CompanyID: 5 }
},
{
    Clicks: 35,
    Company: "C",
    _id: { CompanyID: 3 }
},
{
    Clicks: 15,
    Company: "B",
    _id: { CompanyID: 2 }
},
{
    Clicks: 13,
    Company: "A",
    _id: { CompanyID: 5 }
}]

And want to reduce it to this form:

[{
    Clicks: 223,
    Company: "A",
    _id: { CompanyID: 5 }
},
{
    Clicks: 35,
    Company: "C",
    _id: { CompanyID: 3 }
},
{
    Clicks: 15,
    Company: "B",
    _id: { CompanyID: 2 }
}]

Here is my not correctly working solution so far:

$scope.reduce = function () {
    var result = [];
    var prev = null;

    angular.forEach($scope.data, function (value, key) {
        if (prev != null) {
            if (prev._id.CompanyID != value._id.CompanyID) {
                result.push(prev);
                prev = value;
            } else {
                prev.Clicks += value.Clicks;
            }
        } else {
            prev = value;
        }
    });
}

My result looks good, it reduce all duplicates but it does not sum the values of objects with the same ids, it just overrides the ids with the last object.


回答1:


You can use thisArg parameter in forEach loop and pass a empty object to store values.

var data = [{"Clicks":210,"Company":"A","_id":{"CompanyID":5}},{"Clicks":35,"Company":"C","_id":{"CompanyID":3}},{"Clicks":15,"Company":"B","_id":{"CompanyID":2}},{"Clicks":13,"Company":"A","_id":{"CompanyID":5}}];
var result = [];

data.forEach(function(obj) {
  var id = obj._id.CompanyID
  if(!this[id]) result.push(this[id] = obj);
  else this[id].Clicks += obj.Clicks;
}, Object.create(null));

console.log(result);



回答2:


For a version with Array#reduce, you could use a hash table as reference to the same company with a closure over the hash table.

var data = [{ Clicks: 210, Company: "A", _id: { CompanyID: 5 } }, { Clicks: 35, Company: "C", _id: { CompanyID: 3 } }, { Clicks: 15, Company: "B", _id: { CompanyID: 2 } }, { Clicks: 13, Company: "A", _id: { CompanyID: 5 } }],
    result = data.reduce(function (hash) {
        return function (r, a) {
            var key = a._id.CompanyID;
            if (!hash[key]) {
                hash[key] = { Clicks: 0, Company: a.Company, _id: a._id };
                r.push(hash[key]);
            }
            hash[key].Clicks += a.Clicks;
            return r;
        };
    }(Object.create(null)), []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }


来源:https://stackoverflow.com/questions/44332180/merge-objects-with-the-same-id-but-sum-values-of-the-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!