基于数组计算对象的求和值,并用total更新

时间:2017-02-21 11:30:47

标签: javascript jquery grouping

我有一个对象,基本上我需要三个重要参数进行总计算。 例如,我的目标如下:

[
{'Id':1,'ResourceId':1,'StartDate':'01-01-2017','Hours':8,'TotalHrs':8},
{'Id':2,'ResourceId':1,'StartDate':'01-01-2017','Hours':4,'TotalHrs':4},
{'Id':3,'ResourceId':1,'StartDate':'01-03-2017','Hours':4,'TotalHrs':4},
{'Id':4,'ResourceId':1,'StartDate':'01-03-2017','Hours':4,'TotalHrs':4},
{'Id':5,'ResourceId':2,'StartDate':'01-01-2017','Hours':2,'TotalHrs':2},
{'Id':6,'ResourceId':2,'StartDate':'01-01-2017','Hours':4,'TotalHrs':4},
{'Id':7,'ResourceId':2,'StartDate':'01-03-2017','Hours':2,'TotalHrs':2},
]

因此,目前TotalHrs参数与Hours参数值相同。

我希望它对于特定的ResourceId和Startdate来说是完全的。 即如果在数组中,如果ResourceId和Startdate匹配TotalHrs参数,则应该是来自Hours参数的值的总和。

所以最终的数组变成了。

[
{'Id':1,'ResourceId':1,'StartDate':'01-01-2017','Hours':8,'TotalHrs':12},
{'Id':2,'ResourceId':1,'StartDate':'01-01-2017','Hours':4,'TotalHrs':12},
{'Id':3,'ResourceId':1,'StartDate':'01-03-2017','Hours':4,'TotalHrs':8},
{'Id':4,'ResourceId':1,'StartDate':'01-03-2017','Hours':4,'TotalHrs':8},
{'Id':5,'ResourceId':2,'StartDate':'01-01-2017','Hours':2,'TotalHrs':6},
{'Id':6,'ResourceId':2,'StartDate':'01-01-2017','Hours':4,'TotalHrs':6},
{'Id':7,'ResourceId':2,'StartDate':'01-03-2017','Hours':2,'TotalHrs':2},
]

因此,在上面的示例中,ResourceId:1和StartDate:01-01-2017有两次出现,其中小时值为8和4,因此TotalHrs变为8 + 4 = 12。 / p>

此外,我不想分组,我想在结果数组中使用相同数量的元素,但TotalHrs的更新值。

3 个答案:

答案 0 :(得分:0)

使用Array.prototype.reduce()Array.prototype.forEach()函数的简短解决方案:



var data = [ {'Id':1,'ResourceId':1,'StartDate':'01-01-2017','Hours':8,'TotalHrs':8}, {'Id':2,'ResourceId':1,'StartDate':'01-01-2017','Hours':4,'TotalHrs':4}, {'Id':3,'ResourceId':1,'StartDate':'01-03-2017','Hours':4,'TotalHrs':4}, {'Id':4,'ResourceId':1,'StartDate':'01-03-2017','Hours':4,'TotalHrs':4}, {'Id':5,'ResourceId':2,'StartDate':'01-01-2017','Hours':2,'TotalHrs':2}, {'Id':6,'ResourceId':2,'StartDate':'01-01-2017','Hours':4,'TotalHrs':4}, {'Id':7,'ResourceId':2,'StartDate':'01-03-2017','Hours':2,'TotalHrs':2} ];

data.forEach(function (o) {
    o.TotalHrs = this[o.ResourceId + o.StartDate];
}, data.reduce(function (r, o) {
    var k = o.ResourceId + o.StartDate;
    (!r[k])? r[k] = o.TotalHrs : r[k] += o.TotalHrs;
    return r;
}, {}));

console.log(data);




var k = o.ResourceId + o.StartDate; - k这里是一个哈希键字符串,用于对具有相同ResourceIdStartDate属性的条目进行分组

答案 1 :(得分:0)

我建议使用一个临时对象,使用StartDateResourceId作为哈希键来存储小时数。该算法提供O(n)时间复杂度。

var data = [{'Id':1,'ResourceId':1,'StartDate':'01-01-2017','Hours':8},{'Id':2,'ResourceId':1,'StartDate':'01-01-2017','Hours':4},{'Id':3,'ResourceId':1,'StartDate':'01-03-2017','Hours':4},{'Id':4,'ResourceId':1,'StartDate':'01-03-2017','Hours':4},{'Id':5,'ResourceId':2,'StartDate':'01-01-2017','Hours':2},{'Id':6,'ResourceId':2,'StartDate':'01-01-2017','Hours':4},{'Id':7,'ResourceId':2,'StartDate':'01-03-2017','Hours':2}];

function populateTotalHrs(collection) {
  var collectionByHash = {};
  collection.forEach(function(obj) {
    var hash = obj.ResourceId + '_' + obj.StartDate;
    collectionByHash[hash] = collectionByHash[hash] || 0;
    collectionByHash[hash] += obj.Hours;
  });
  collection.forEach(function(obj) {
    var hash = obj.ResourceId + '_' + obj.StartDate;
    obj.TotalHrs = collectionByHash[hash];
  });  
}

populateTotalHrs(data);
console.log(data);

答案 2 :(得分:0)

您可以使用哈希表并按ResourceIdStartDate对其进行临时分组。

var data = [{ Id: 1, ResourceId: 1, StartDate: '01-01-2017', Hours: 8, TotalHrs: 8 }, { Id: 2, ResourceId: 1, StartDate: '01-01-2017', Hours: 4, TotalHrs: 4 }, { Id: 3, ResourceId: 1, StartDate: '01-03-2017', Hours: 4, TotalHrs: 4 }, { Id: 4, ResourceId: 1, StartDate: '01-03-2017', Hours: 4, TotalHrs: 4 }, { Id: 5, ResourceId: 2, StartDate: '01-01-2017', Hours: 2, TotalHrs: 2 }, { Id: 6, ResourceId: 2, StartDate: '01-01-2017', Hours: 4, TotalHrs: 4 }, { Id: 7, ResourceId: 2, StartDate: '01-03-2017', Hours: 2, TotalHrs: 2 }];

data.forEach(function (hash) {
    return function (a) {
        var key = [a.ResourceId, a.StartDate].join('|');
        if (!hash[key]) {
            hash[key] = [a];
            return;
        }
        hash[key].push(a);
        hash[key][0].TotalHrs += a.Hours;
        hash[key].forEach(function (b) {
            b.TotalHrs = hash[key][0].TotalHrs;
        });
    };
}(Object.create(null)));

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