问题
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