合并具有相同id但对象的和值的对象

时间:2017-06-02 15:12:24

标签: javascript group-by reduce

我希望通过比较数组中的先前和当前对象来减少我的对象数组,如果前一个对象的id与当前对象不同,那么我将前一个对象写入我的结果列表并用当前对象覆盖它否则我总结两个对象的值。最后它应该是一个简化的数组,没有重复。

我有这样的数据:

[{
    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 }
}]

并希望将其缩小为这种形式:

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

到目前为止,这是我不正确的解决方案:

$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;
        }
    });
}

我的结果看起来不错,它减少了所有重复项,但它没有对具有相同ID的对象的值求和,它只是覆盖了最后一个对象的id。

2 个答案:

答案 0 :(得分:4)

您可以在thisArg循环中使用forEach参数,并传递一个空对象来存储值。

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);

答案 1 :(得分:3)

对于Array#reduce的版本,您可以使用哈希表作为对具有哈希表闭包的同一公司的引用。

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; }