Search code examples
javascriptrecursioncounterpapaparse

How to create a counter using recursion to get the total employees(direct or indirect) under a manager_id in javascript?


I have an excel file with data like this

Name WorkerId ManagerId
Tom 179 180
Liz 150 179
Ricki 120 179
sona 113 150
Preet 558 150
mina 89 558
Yukti 45 120

And I want a function CountEmployee(manager_id) that will return all the employees under him. For example:

CountEmployee(179) = 6 , CountEmployee(150) = 3

I am using papa parse library to parse this excel into object, and wrote an recursive function to get the total employee.

parseCsv to parse the csv

 function parseCsv() {
  return new Promise((resolve, reject) => {
    Papa.parse("Employees.csv", {
      download: true,
      complete: function (results) {
        return resolve(results);
      },
    });
  });
}

CountDirectEmployees to get the Direct employees of a manager Id

 async function CountDirectEmployee(data) {
      var countDirect1 = 0
       const results = await parseCsv();
        results.data.map((row, index) => {
                        if (row[2] == data) {
                           countDirect1 = countDirect1 +  1
                        }
                    })
     return countDirect1;
    }

And finally,

The CountEmployee should return the final count

 async function CountEmployee(data,count) {
         const results = await parseCsv();
         CountDirectEmployee(data).then(
         function(count1){

         results.data.forEach((row, index) => {
                         if (row.ManagerId == data) {
                     count1 = count+count1
               CountEmployee(row[1],count1)
              }
         })
        } 
        )
       return count
   }

I know my logic is wrong for CountEmployee function, somewhere. Not able to figure out the issue.


Solution

  • Changing the code slightly will allow us to call CountEmployee recursively. We'd pass in the rows variable for each call (to save reading in repeatedly), then add each employee's direct worker count to get the total for each manager.

    The getDirectEmployees() function uses a simple Array.filter() to return the employees working directly for each manager.

    const employees = [ 
        [ 'Tom', 179, 180 ],
        [ 'Liz', 150, 179 ],
        [ 'Ricki', 120, 179 ],
        [ 'Sona', 113, 150 ],
        [ 'Preet', 558, 150 ],
        [ 'Mina', 89, 558 ],
        [ 'Yukti', 45, 120 ]
    ];
        
    // Simulate what papa parse returns...
    function parseCSV() {
        return Promise.resolve(employees); 
    }
    
    function displayRow(...row) {
        console.log(...row.map(f => (f + '').padEnd(15)))
    }
    
    async function testCounts() {
        console.log('Direct and total counts for each worker:\n');
    
        let rows = await parseCSV();
        displayRow('Name', 'Id', 'Direct', 'Total')
        for(let [name, workerId, managerId] of rows) {
            let directEmployees = CountDirectEmployees(workerId, rows);
            let totalEmployees = CountEmployee(workerId, rows);
            displayRow(name, workerId, directEmployees, totalEmployees)
        }
    }
    
    function getDirectEmployees(id, rows) {
        return rows.filter(([name, workerId, managerId]) => managerId === id);
    }
    
    function CountDirectEmployees(managerId, rows) {
        return getDirectEmployees(managerId, rows).length;
    }
     
    function CountEmployee(managerId, rows) {
        // Count direct employees, then count employees of each of these
        let directEmployees = getDirectEmployees(managerId, rows);
        let count = directEmployees.length;
        for(let [name, workerId] of directEmployees) {
            count += CountEmployee(workerId, rows);
        }
        return count;
    }
     
    testCounts()
     
    .as-console-wrapper { max-height: 100% !important; top: 0; }