What is the method for determining the total number of hours?

Having trouble calculating total hours based on "employeeId"? Need help with the logic to solve this problem efficiently.

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 array = 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 res = response.responseText;
          var resObj = Ext.decode(res);
          for(var j = 0; j < resObj.data.length; j++)
              {
                 for(var k = 0; k < resObj.data[j].payrolltransactionDetail.length; k++) 
                 {
                    array.push(resObj.data[j].payrolltransactionDetail[k]);
                 }
              }
              console.log(JSON.stringify(array, null, 4));
        }
        catch(e){
          console.log(e);
        }
      },
      failure: function(response){
        deferred.reject("Error Fetching.");
      }
    });

Answer №1

Using functional programming in JavaScript, you have the ability to manipulate data efficiently by utilizing the reduce function. If for some reason you are unable to modify your query result through server-side aggregation, you can implement a solution similar to the one outlined 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 (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;
     }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);

Answer №2

Take a look at this improved implementation that I believe is more organized compared to other solutions:

function calculateTotalHours(data) {
    const seenEmployees = {};
    const aggregatedResults = [];

    data.forEach(entry => {
        const employeeId = entry.employeeId;
        if (!seenEmployees.hasOwnProperty(employeeId)) {
            seenEmployees[employeeId] = aggregatedResults.length;
            aggregatedResults.push({
                employeeId: employeeId,
                minutes: 0
            });
        }
        const index = seenEmployees[employeeId];
        const timeParts = entry.totalHours.split(':');
        aggregatedResults[index].minutes += (parseInt(timeParts[0], 10) * 60) + parseInt(timeParts[1]);
    });

    aggregatedResults.forEach(entry => {
        const totalMinutes = entry.minutes;
        delete entry.minutes;
        entry.totalHours = Ext.String.leftPad(Math.floor(totalMinutes / 60), 2, '0') 
                            + ':' + Ext.String.leftPad(totalMinutes % 60, 2, '0');
    });

    return aggregatedResults;
}

console.log(calculateTotalHours([{
    "employeeId": "105",
    "totalHours": "1:30"
}, {
    "employeeId": "777",
    "totalHours": "1:15"
}, {
    "employeeId": "105",
    "totalHours": "1:15"
}, {
    "employeeId": "777",
    "totalHours": "1:00"
}]));

Answer №3

// This code snippet is designed to handle custom object input and calculate total hours for each employee.
var result={};
for(i=0;i<input.length;i++){
el = input[i];
a=result[el.id];
a.employeeId=el.employeeId;
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(":");
}

However, the output may not meet expectations since searching the employee id in the array repeatedly was not the intended approach:

{
105:{
   employeeId:105;
   totalHours:"15:20";
 }
 }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The sticky navigation bar hack (implementing fixed positioning with jQuery)

Essentially, when the navigation bar (or any other element) reaches the top of the page or window, a class called "sticky" is added to the element and CSS styles it as fixed. This functionality acts like an IF statement - if the element is far from the top ...

Guide on Wrapping a File and Piping it to a New File within the Same Directory using Gulp

I'm in the process of developing a Gulp build system that has the following requirements: Extract HTML files from each directory Enclose the HTML files with additional HTML markup Generate a new file named wrapped.html Place the new file back into t ...

Verify that the data attribute is not blank

I would like to iterate through all the td cells in a table and examine their data attributes. If the attribute contains a value, I want to display it using console.log. Currently, I have the following code but it is not functioning as expected (it merely ...

concentrate on the input box

Once I click on the CPM, my goal is to automatically place the cursor in the centralized field of this page: . Despite my attempts to use different code snippets in the console, I have not been successful. I experimented with document.getElementById("se ...

Imported function encounters a non-function error

I'm encountering a puzzling reference/binding error that I can't seem to resolve: import React from 'react'; var { View, StyleSheet, Alert, AsyncStorage } = require('react-native'); import {Button} from 'react-native-el ...

Is there a way to swap out images when a button is clicked and the PHP script has completed its execution

Seeking guidance on this matter: I have a PHP file containing HTML code. The page displays 8 images and 1 button. I click the button A POST request triggers some PHP code, providing me with a random number between 1-8 7 images have their "src" attribute ...

Display the device model using Google Cloud Monitoring API

I've been utilizing a Node.js library to fetch metrics from my Google Cloud Compute Engine instances. You can find the library here. When creating a time series, the resulting data looks like this: { "points": [...], "metric": { "lab ...

What is the best way to link this to a function in AngularIO's Observable::subscribe method?

Many examples use the Observable.subscribe() function in AngularIO. However, I have only seen anonymous functions being used like this: bar().subscribe(data => this.data = data, ...); When I try to use a function from the same class like this: update ...

Checking for queryParam changes in Angular before ngOnDestroy is invoked

I am looking to conditionally run some code in the ngOnDestroy function depending on changes in the current route. Specifically, when the route changes from /foo to /login?logout=true, and this change is initiated outside of the Foo component. In the ngO ...

The error "Uncaught TypeError: Cannot read property 'render' of undefined" occurs when using Three.js along with OrbitControls

I am having an issue with my rotating cube class. Whenever I try to rotate or zoom the cube, I encounter an error message saying "Cannot read property 'render' of undefined". I suspect that the problem lies within the scopes. Below is my class im ...

When the user clicks, reveal the form with a seamless transition

Check out my jsfiddle here: http://jsfiddle.net/tz52u/9/ I'm curious about how to create a smooth transition for the 'on click' event, so that it gradually appears on the page instead of appearing instantly? Any assistance would be greatl ...

What is the best way to retrieve the parameters from the current URL within an Express function on the backend? (details below)

Struggling to articulate my issue here. I'm in the process of creating a straightforward express app that utilizes the omdb API to search for movie titles and display the results. The challenge is that the omdb API returns the results in pages, with 1 ...

Disable Three.js when WebGL is not supported: Tips and tricks

I read about how to switch to canvasrenderer if webgl is not supported. renderer = Detector.webgl? new THREE.WebGLRenderer(): new THREE.CanvasRenderer(); I'm not sure how to completely remove everything if webgl is not detected. I have an image in t ...

Error in Wordpress Frontend Ajax: The variable ajaxurl is not defined in wp_localize_script

My current challenge involves creating markers on a map using ajax within a Wordpress theme. Despite several attempts, I discovered that I cannot utilize a PHP file to retrieve data via ajax; instead, I must use the admin-ajax.php file. Following numerous ...

"File Uploader Control indicating the absence of a file with Has File set

Currently I have implemented a File Upload Control within an Update Panel, with the trigger setting as shown below: <Triggers> <ajax:PostBackTrigger ControlID="btnAdd" /> </Triggers> Despite this setup, the Has F ...

Delays in State Transitions with Angular UI-Router's Nested Views

Currently, I am facing an issue with my parent view that contains a nested view in the middle. Whenever there is a state change, the nested view seems to lag behind for a moment before loading the next state. It's like the nested view is taking a whi ...

What is the best way to access a scope variable within a directive in Angular?

I need to access a scope variable within a directive as a JavaScript variable. Here is the code snippet: app.controller("Home", ["$scope", function($scope) { ... $scope.nb_msg = data.length; ... }]); app.directive("myDiv", function() { // ...

Customizing blockquote styling in QuillJS with a unique class

Currently, I am exploring a method to include a custom class when the user selects the blockquote toolbar button. When the blockquote is clicked, it generates the following element: <blockquote class="ql-align-justify">this is my quoted tex ...

I attempted to install react-compare-image using npm, but encountered an error stating that the dependency tree could not be resolved

PS D:\skinprojecct> npm install --save react-compare-image npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: [email protected] npm ERR! Found: [email protected] npm ERR! node_mod ...

Retrieving the <select> value seamlessly without the need to submit or refresh the page

I'm currently experimenting with a cart functionality but facing issues making it work. I am trying to create a shopping cart where I can update the quantity of each product using a drop-down list (<select>) and have the price updated automatica ...