我有一个对象,基本上我需要三个重要参数进行总计算。 例如,我的目标如下:
[
{'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
的更新值。
答案 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
这里是一个哈希键字符串,用于对具有相同ResourceId
和StartDate
属性的条目进行分组
答案 1 :(得分:0)
我建议使用一个临时对象,使用StartDate
和ResourceId
作为哈希键来存储小时数。该算法提供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)
您可以使用哈希表并按ResourceId
和StartDate
对其进行临时分组。
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; }