Search code examples
javascriptarraysnode.jsobjectresponse

JavaScript extract matched ids for array of objects


I have an array of objects containing employeeProjectId which might be same. So what I am looking for is that if there is more than one same employeeProjectId then merge the results into one object with having projectRoles in the form of array. Response is given below for reference. Thankyou :)

{
"code": 200,
"success": true,
"message": "Successfully completed",
"data": [
    {
        "employeeProjectId": 1,
        "projectRoleId": 1,
        "employee_project": {
            "id": 1,
            "status": true,
            "type": "backup",
            "startDate": "2018-06-28T07:20:36.000Z",
            "endDate": "2018-06-29T07:20:39.000Z",
            "allocation": 100,
            "employeeId": 326,
            "projectId": 35,
            "employee": {
                "firstName": "Asad",
                "lastName": "Marfani"
            },
            "project": {
                "name": "RTA"
            }
        },
        "project_role": {
            "id": 1,
            "role": "front_end_ios"
        }
    },
    {
        "employeeProjectId": 1,
        "projectRoleId": 2,
        "employee_project": {
            "id": 1,
            "status": true,
            "type": "backup",
            "startDate": "2018-06-28T07:20:36.000Z",
            "endDate": "2018-06-29T07:20:39.000Z",
            "allocation": 100,
            "employeeId": 326,
            "projectId": 35,
            "employee": {
                "firstName": "Asad",
                "lastName": "Marfani"
            },
            "project": {
                "name": "RTA"
            }
        },
        "project_role": {
            "id": 2,
            "role": "Front End - Android"
        }
    },
    {
        "employeeProjectId": 3,
        "projectRoleId": 1,
        "employee_project": {
            "id": 3,
            "status": true,
            "type": "backup",
            "startDate": "2018-06-28T07:47:19.000Z",
            "endDate": "2018-06-29T07:47:22.000Z",
            "allocation": 50,
            "employeeId": 16,
            "projectId": 35,
            "employee": {
                "firstName": "Nosheen",
                "lastName": "Sikandar"
            },
            "project": {
                "name": "RTA"
            }
        },
        "project_role": {
            "id": 1,
            "role": "front_end_ios"
        }
    },
    {
        "employeeProjectId": 3,
        "projectRoleId": 3,
        "employee_project": {
            "id": 3,
            "status": true,
            "type": "backup",
            "startDate": "2018-06-28T07:47:19.000Z",
            "endDate": "2018-06-29T07:47:22.000Z",
            "allocation": 50,
            "employeeId": 16,
            "projectId": 35,
            "employee": {
                "firstName": "Nosheen",
                "lastName": "Sikandar"
            },
            "project": {
                "name": "RTA"
            }
        },
        "project_role": {
            "id": 3,
            "role": "Front End - Web"
        }
    }
]}

I want it like this :

{
"code": 200,
"success": true,
"message": "Successfully completed",
"data": [
    {
        "employeeProjectId": 1,
        "employee_project": {
            "id": 1,
            "status": true,
            "type": "backup",
            "startDate": "2018-06-28T07:20:36.000Z",
            "endDate": "2018-06-29T07:20:39.000Z",
            "allocation": 100,
            "employeeId": 326,
            "projectId": 35,
            "employee": {
                "firstName": "Asad",
                "lastName": "Marfani"
            },
            "project": {
                "name": "RTA"
            }
        },
        "project_role": [
            {
                "id": 1,
                "role": "front_end_ios",
             },
             {
                "id": 2,
                "role": "front_end_web"
             }
        ]
    }
]}

Solution

  • You could use map to create an array of groups (employeeProjectIds) and reduce the array into groups using that array.

    I have a feeling that fields in employee_project also need to be merged since start, end date and allocation are unique for the employee and and project.

    Then map the array of groups in merged data:

    const data = [{"employeeProjectId":1,"project_role":"a"},{"employeeProjectId":1,"project_role":"b"},{"employeeProjectId":3,"project_role":"a"},{"employeeProjectId":3,"project_role":"c"}];
    const groupBy = (getGroup,array) => {
      //use getGroup function to get the group identifyer of the items (is employeeProjectId)
      const groups = array.map(getGroup);
      return array.reduce(//reduce array into array of arrays that are grouped
        (result,item,index)=>{
          //get the group of current item
          const itemGroup = getGroup(item);
          //find the index of this item in groups
          const indexOfGroup = groups.indexOf(itemGroup);
          //index of this item in groups is current index so it's first item of the group
          if(indexOfGroup===index){
            return result.concat([[item]])
          }
          //it is not first item of the group, add this item to it's correct group
          //add current item to the right group
          result.find(([item])=>getGroup(item)===itemGroup).push(item);
          return result;
        },
        []//initial result
      )
    }
    
    const merge = (item1,item2) => {
      //if project_role is not an array yet, make it an array
      if(!Array.isArray(item1.project_role)){
        item1 = {...item1,project_role:[item1.project_role]};
      }
      //add project_role of item2 to item1
      item1.project_role.push(item2.project_role);
      return item1;
    };
    
    const grouped = groupBy(x=>x.employeeProjectId,data);
    console.log("grouped",grouped);
    
    console.log(
      "grouped and merged",
      groupBy(x=>x.employeeProjectId,data).map(
        group=>
          group.reduce(merge)
      )
    )

    There may be some syntax you are unfamiliar with like spread in object literals to copy an object (not a deep copy), arrow functions and destructuring assignment used when it's trying to find an element in an array.

    The map and reduce methods are documented here