Reputation: 355
Suppose I have response array from my web-service like this
Array1 = [
0:[{name:A,count:2,hours:3},{name:B,count:3,hours:3},{name:C,count:2,hours:4}]
1:[{name:A,count:3,hours:4},{name:B,count:3,hours:3},{name:C,count:2,hours:2}]
2:[{name:A,count:3,hours:1},{name:B,count:3,hours:4},{name:C,count:2,hours:5},{name:D,count:2,hours:3}]
];
and
Array2 = ['A','B','C','D'];
In my output, I need to check for 24 hours.But for simplicity,we will now take only hours to 5.Each sub array from Array1 belong to one user. Now,I must group array by hours and activity. Means I need to make key as name and value as total count of name in each hours.
And output must look like this
var output = [
{hours:1, A:3, B:0, C:0, D:0},
{hours:2, A:0, B:0, C:2, D:0},
{hours:3, A:2, B:6, C:0, D:2},
{hours:4, A:3, B:3, C:2, D:0},
{hours:5, A:0, B:0, C:2, D:0},
];
And my try below
angular.forEach(Array1 , function(array){ //angularjs foreach
array.forEach(function(a){
obj[a.hours] = obj[a.hours]||[0];
if(obj[a.hours].hasOwnProperty(a.name)){
obj[a.hours][a.name] = parseInt(obj[a.hours][a.name]) + parseInt(a.count);
}else{
obj[a.hours][a.name] = parseInt(a.count);
}
obj[a.hours]['hours'] = a.hours;
});
});
where I try to group my array with hours and name as key and total count as value. What more I try is
var startHour = 1;
var endHours = 5;
var newData = []; //@TODO
newData.push(obj); //@TODO
for(i= startDate; i < endDate; i++) {
var found = newData.some(function(el){
//el.forEach(function(a){
$.each(el, function(key, value) {
if(value.hours){
return value.hours === i;
}
});
});
if(!found){
console.log(i + "not found");
newData.push([{'hours':i}]);
}
}
console.log(newData);
But every time I am in not found.As my output I need to push key-value pairs name and count 0 if not exit. But first I try to push only hours if not exists. Can anyone suggest me what I did wrong. I am back-end programmer so,I don't have good knowledge of JavaScript.
Thank You.
Upvotes: 1
Views: 1022
Reputation: 386883
You could use a hash table for the reference of the right hour object and iterate the data with Array#forEach
. Later sort the result array for the wanted order.
var array1 = [[{ name: 'A', count: 2, hours: 3 }, { name: 'B', count: 3, hours: 3 }, { name: 'C', count: 2, hours: 4 }], [{ name: 'A', count: 3, hours: 4 }, { name: 'B', count: 3, hours: 3 }, { name: 'C', count: 2, hours: 2 }], [{ name: 'A', count: 3, hours: 1 }, { name: 'B', count: 3, hours: 4 }, { name: 'C', count: 2, hours: 5 }, { name: 'D', count: 2, hours: 3 }]],
array2 = ['A', 'B', 'C', 'D'],
grouped = [];
array1.forEach(function (a) {
a.forEach(function (b) {
if (!this[b.hours]) {
this[b.hours] = { hours: b.hours };
array2.forEach(function (c) { this[c] = 0; }, this[b.hours]);
grouped.push(this[b.hours]);
}
this[b.hours][b.name] += b.count;
}, this);
}, Object.create(null));
grouped.sort(function (a, b) { return a.hours - b.hours; });
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Proposal with 24h array, with zero based hour
.
var array1 = [[{ name: 'A', count: 2, hours: 3 }, { name: 'B', count: 3, hours: 3 }, { name: 'C', count: 2, hours: 4 }], [{ name: 'A', count: 3, hours: 4 }, { name: 'B', count: 3, hours: 3 }, { name: 'C', count: 2, hours: 2 }], [{ name: 'A', count: 3, hours: 1 }, { name: 'B', count: 3, hours: 4 }, { name: 'C', count: 2, hours: 5 }, { name: 'D', count: 2, hours: 3 }]],
array2 = ['A', 'B', 'C', 'D'],
grouped = Array.apply(null, { length: 24 }).map(function (_, i) {
var o = { hours: i }
array2.forEach(function (a) { this[a] = 0; }, o);
return o;
});
array1.forEach(function (a) {
a.forEach(function (b) {
grouped[b.hours][b.name] += b.count;
}, this);
}, Object.create(null));
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 4612
You could start on a array of object (1 object per hour). And pushing inside this array the new additional count coresponding the hour and name :
var Array1 = [[{name: "A",count: 2,hours: 3},{name: "B",count: 3,hours: 3},{name: "C",count: 2,hours: 4}],[{name: "A",count: 3,hours: 4},{name: "B",count: 3,hours: 3},{name: "C",count: 2,hours: 2}],[{name: "A",count: 3,hours: 1},{name: "B",count: 3,hours: 4},{name: "C",count: 2,hours: 5},{name: "D",count: 2,hours: 3}]];
var Array2 = ['A','B','C','D'];
var res = [1,2,3,4,5].map(x => ({"hours": x})).map(x => {
Array2.forEach(y => x[y] = 0);
return x;
});
Array1.reduce((a,b) => a.concat(b)).forEach(x => {
if (Array2.indexOf(x.name) !== -1)
res[x.hours - 1][x.name] += x.count;
})
console.log(res);
Upvotes: 0