JavaScript extract matched ids for array of objects
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"
}
]
}
]}
projectRoleId
Use object.keys(object) to save your objects key in an array and compare to see whether there's an employeeProjectId. Then with a loop you should be able to the merge the properties.
– leonardofed
Jun 28 at 12:03
Sorry @HMR it was a typo. I have edited the result I want.
– Asad Marfani
Jun 28 at 12:06
array of objects is not the same type as single object so when processing it later you may have some difficulties parsing it.
– HMR
Jun 28 at 12:27
Yeah you are right. I think make it always an array of object is a good thing. If there is a single project_role then there there will be one object in the project_role array. That means its length will be one in this case
– Asad Marfani
Jun 28 at 12:30
2 Answers
2
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.
employee_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
Thank you so much @HMR. I have been looking solutions but did not get the this structured approach anywhere. You are the life saver :)
– Asad Marfani
Jun 29 at 7:55
what if I have more then two project roles? Its giving me error. ` result[offset - 1].push(item);`
Cannot read property 'push' of undefined
– Asad Marfani
2 days ago
Cannot read property 'push' of undefined
@AsadMarfani I fixed a bug in the code, it was not correctly adding the item to the right group. Should be fixed with the update.
– HMR
2 days ago
Awesome @HMR. Its working now :) There is so much to learn from your code.
– Asad Marfani
2 days ago
@AsadMarfani 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.
– HMR
2 days ago
I guess you are looking for something like this :D
else you also can use the lodash module.
const obj = {
"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"
}
}
]}
const data = obj.data
const res = data.filter(emp => {
return emp.employee_project.id == "1"
}).reduce(item => {
return item
})
console.log(res)
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Should
projectRoleId
not also be an an array and I think your result does not reflect what you like it to be, there are 2 project_role objects that are the same (same id and role).– HMR
Jun 28 at 12:00