Reputation: 47
I am trying to calculate total hours based on "employeeId". I couldn't figure out how to write logic for this. What is the best way to solve this problem?
Expected Result,
[
{
"employeeId": "105",
"totalHours": "2:45"
},
{
"employeeId": "777",
"totalHours": "2:15"
}
]
Response From Ajax Call
[
{
"employeeId": "105",
"totalHours": "1:30"
},
{
"employeeId": "777",
"totalHours": "1:15"
},
{
"employeeId": "105",
"totalHours": "1:15"
},
{
"employeeId": "777",
"totalHours": "1:00"
}
]
My Code
var jrr = new Array();
Ext.Ajax.request({
url: '/common/services/general/basicOperations/getDataByModelUsingGetMethod',
method: 'GET',
params : {
actionId : 'payroll',
dataJson : '{"aspectType":"Payroll Profile"}'
},
success: function(response){
try{
var response = response.responseText;
var resObj = Ext.decode(response);
for(var j = 0; j < resObj.data.length; j++)
{
for(var k = 0; k < resObj.data[j].payrolltransactionDetail.length; k++)
{
jrr.push(resObj.data[j].payrolltransactionDetail[k]);
}
}
console.log(JSON.stringify(jrr, null, 4));
}
catch(e){
console.log(e);
}
},
failure: function(response){
deferred.reject("Error Fetching.");
}
});
Upvotes: 1
Views: 200
Reputation: 1161
Here is an implementation using js functional programming. You can transform the data to your desired output using just the reduce function. If you cannot change your query result using some kind of aggregation on the server side then you can implement something akin to the below.
var input = [
{
"employeeId": "105",
"totalHours": "1:46"
},
{
"employeeId": "777",
"totalHours": "1:15"
},
{
"employeeId": "105",
"totalHours": "1:15"
},
{
"employeeId": "777",
"totalHours": "1:00"
}
]
var obj = input.reduce( function(init, e){
//if aggregating init object doesn't have the employee then add the employeeId (key) and time (value)
if (init[e["employeeId"]] == undefined){
init[e["employeeId"]] = {
hours: parseInt(e["totalHours"].split(":")[0]),
minutes: parseInt(e["totalHours"].split(":")[1])
};
init[e["employeeId"]].timeString = e["totalHours"];
return init;
//otherwise add to the existing employeeId the hour and minute values, while remembering to carry the extra hour if minutes exceed 59.
}else{
init[e["employeeId"]].hours +=
(parseInt(e["totalHours"].split(":")[0]) +
Math.floor((init[e["employeeId"]].minutes +
parseInt(e["totalHours"].split(":")[1]))/60));
init[e["employeeId"]].minutes =
(init[e["employeeId"]].minutes +
parseInt(e["totalHours"].split(":")[1]))%60;
init[e["employeeId"]].timeString =
init[e["employeeId"]].minutes > 9 ?
init[e["employeeId"]].hours + ":" + init[e["employeeId"]].minutes :
init[e["employeeId"]].hours +
":0" + init[e["employeeId"]].minutes;
return init;
}
}, {});
var arr = [];
for (var prop in obj) arr.push({employeeId: prop, totalHours: obj[prop].timeString});
console.log(arr);
Upvotes: 1
Reputation: 138267
// Expecting input to be your custom object
var output={};
for(i=0;i<input.length;i++){
el = input[i];
a=output[el.id];
a.employeId=el.employeId;
a.totalHours=a.totalHours||"0:0";
b=el.totalHours.split(":");
c=a.totalHours.split(":");
b[0]=+b[0]+c[0];
if(b[1]+c[1]>60){
b[0]++;
}
b[1]=(+b[1]+c[1])%60;
a.totalHours=b.join(":");
}
The result is not exactly what youve expected. I dont wanted to search the employe id in the array each times:
{
105:{
employeid:105;
totalHours:"15:20";
}
}
Upvotes: 0
Reputation: 30082
Here is an implementation. I think it's cleaner than some of the other answers:
function calc(data) {
const seen = {};
const result = [];
data.forEach(item => {
const id = item.employeeId;
if (!seen.hasOwnProperty(id)) {
seen[id] = result.length;
result.push({
employeeId: id,
minutes: 0
});
}
const idx = seen[id];
const parts = item.totalHours.split(':');
result[idx].minutes += (parseInt(parts[0], 10) * 60) + parseInt(parts[1]);
});
result.forEach(item => {
const minutes = item.minutes;
delete item.minutes;
item.totalHours = Ext.String.leftPad(Math.floor(minutes / 60), 2, '0')
+ ':' + Ext.String.leftPad(minutes % 60, 2, '0');
});
return result;
}
console.log(calc([{
"employeeId": "105",
"totalHours": "1:30"
}, {
"employeeId": "777",
"totalHours": "1:15"
}, {
"employeeId": "105",
"totalHours": "1:15"
}, {
"employeeId": "777",
"totalHours": "1:00"
}]));
Upvotes: 1