简体   繁体   中英

Not able to calculate total hours

I am new to JavaScript. We have a code to add total hours based on "employee id". Below code showing correct result for "excessTime". But for "totalHours" it is showing "NaN". Does anyone know why it is showing "NaN" while adding "totalHours" and How to fix it?

<!DOCTYPE html>
<html>
<body>
<script>
var input = [
    {
        "employeeId": "101",
        "totalHours": "1:46",
        "excessTime": "2:15"
    },
    {
        "employeeId": "102",
        "totalHours": "1:15",
        "excessTime": "1:30"
    },
    {
        "employeeId": "101",
        "totalHours": "1:15",
        "excessTime": "3:00"
    },
    {
        "employeeId": "102",
        "totalHours": "1:00",
        "excessTime": "2:15"
    }
]

    var obj = input.reduce( function(init, e){
    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"];
         init[e["employeeId"]] = {hrs: parseInt(e["excessTime"].split(":")[0]),mns: parseInt(e["excessTime"].split(":")[1])};
         init[e["employeeId"]].excessString = e["excessTime"];
         return init;
      } 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;

         init[e["employeeId"]].hrs += (parseInt(e["excessTime"].split(":")[0]) + Math.floor((init[e["employeeId"]].mns + parseInt(e["excessTime"].split(":")[1]))/60));
         init[e["employeeId"]].mns = (init[e["employeeId"]].mns + parseInt(e["excessTime"].split(":")[1]))%60;
         init[e["employeeId"]].excessString = init[e["employeeId"]].mns > 9 ? init[e["employeeId"]].hrs + ":" + init[e["employeeId"]].mns : init[e["employeeId"]].hrs + ":0" + init[e["employeeId"]].mns;
         return init;
      }
  }, {});

var arr = [];
for (var prop in obj) arr.push({employeeId: prop, totalHours: obj[prop].timeString, excessTime: obj[prop].excessString});
console.log(arr);
</script>
</body>
</html>

Output:

[
    {
        "employeeId": "101",
        "totalHours": "NaN:0NaN",
        "excessTime": "5:15"
    },
    {
        "employeeId": "102",
        "totalHours": "NaN:0NaN",
        "excessTime": "3:45"
    }
]

You are attempting to assign values to the hours and minutes properties, but they are undefined . You need to assign them to their hours and minutes respectively in your first if statement:

init[e["employeeId"]].hours = parseInt(e["totalHours"].split(":")[0]);
init[e["employeeId"]].minutes = parseInt(e["totalHours"].split(":")[1]);

All together looks like this:

var input = [
    {
        "employeeId": "101",
        "totalHours": "1:46",
        "excessTime": "2:15"
    },
    {
        "employeeId": "102",
        "totalHours": "1:15",
        "excessTime": "1:30"
    },
    {
        "employeeId": "101",
        "totalHours": "1:15",
        "excessTime": "3:00"
    },
    {
        "employeeId": "102",
        "totalHours": "1:00",
        "excessTime": "2:15"
    }
]

    var obj = input.reduce( function(init, e){
    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"];
         init[e["employeeId"]] = {hrs: parseInt(e["excessTime"].split(":")[0]),mns: parseInt(e["excessTime"].split(":")[1])};
         init[e["employeeId"]].excessString = e["excessTime"];
         init[e["employeeId"]].hours = parseInt(e["totalHours"].split(":")[0]);
         init[e["employeeId"]].minutes = parseInt(e["totalHours"].split(":")[1]);
         return init;
      } 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;

         init[e["employeeId"]].hrs += (parseInt(e["excessTime"].split(":")[0]) + Math.floor((init[e["employeeId"]].mns + parseInt(e["excessTime"].split(":")[1]))/60));
         init[e["employeeId"]].mns = (init[e["employeeId"]].mns + parseInt(e["excessTime"].split(":")[1]))%60;
         init[e["employeeId"]].excessString = init[e["employeeId"]].mns > 9 ? init[e["employeeId"]].hrs + ":" + init[e["employeeId"]].mns : init[e["employeeId"]].hrs + ":0" + init[e["employeeId"]].mns;
         return init;
      }
  }, {});

var arr = [];
for (var prop in obj) arr.push({employeeId: prop, totalHours: obj[prop].timeString, excessTime: obj[prop].excessString});
console.log(arr);

Result:

  [{
        "employeeId": "101",
        "totalHours": "3:01",
        "excessTime": "5:15"
    }, {
        "employeeId": "102",
        "totalHours": "2:15",
        "excessTime": "3:45"
    }]

JSFiddle: https://jsfiddle.net/v7eckcny/

这是因为是String,使用parseInt()将字符串转换为整数,如下例所示:

var a = parseInt("10");

Inside your reduce if clause your are initializing init[e["employeeId"]] two times , so when you initializing it second time your {hours , minutes} object getting replaced with {hrs,mns} and thats why you are getting NAN in total hour.

you need to initialize it once

init[e["employeeId"]] = {hours: parseInt(e["totalHours"].split(":")[0]),minutes: parseInt(e["totalHours"].split(":")[1]),hrs: parseInt(e["excessTime"].split(":")[0]),mns: parseInt(e["excessTime"].split(":")[1])};

Have a look on below working code snippet.

 var input = [ { "employeeId": "101", "totalHours": "1:46", "excessTime": "2:15" }, { "employeeId": "102", "totalHours": "1:15", "excessTime": "1:30" }, { "employeeId": "101", "totalHours": "1:15", "excessTime": "3:00" }, { "employeeId": "102", "totalHours": "1:00", "excessTime": "2:15" } ]; var obj = input.reduce( function(init, e){ if (init[e["employeeId"]] == undefined){ // here you need to change your code like below init[e["employeeId"]] = {hours: parseInt(e["totalHours"].split(":")[0]),minutes: parseInt(e["totalHours"].split(":")[1]),hrs: parseInt(e["excessTime"].split(":")[0]),mns: parseInt(e["excessTime"].split(":")[1])}; init[e["employeeId"]].timeString = e["totalHours"]; init[e["employeeId"]].excessString = e["excessTime"]; return init; } 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; init[e["employeeId"]].hrs += (parseInt(e["excessTime"].split(":")[0]) + Math.floor((init[e["employeeId"]].mns + parseInt(e["excessTime"].split(":")[1]))/60)); init[e["employeeId"]].mns = (init[e["employeeId"]].mns + parseInt(e["excessTime"].split(":")[1]))%60; init[e["employeeId"]].excessString = init[e["employeeId"]].mns > 9 ? init[e["employeeId"]].hrs + ":" + init[e["employeeId"]].mns : init[e["employeeId"]].hrs + ":0" + init[e["employeeId"]].mns; return init; } }, {}); var arr = []; for (var prop in obj) arr.push({employeeId: prop, totalHours: obj[prop].timeString, excessTime: obj[prop].excessString}); console.log(arr); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM