首页 > 解决方案 > JavaScript 为对象数组提取匹配的 id

问题描述

我有一个包含可能相同的employeeProjectId的对象数组。所以我正在寻找的是,如果有多个相同的employeeProjectId,则将结果合并到一个对象中,并以数组的形式具有projectRoles。回复如下,供参考。谢谢 :)

{
"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"
        }
    }
]}

我想要这样:

{
"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"
             }
        ]
    }
]}

标签: javascriptarraysnode.jsobjectresponse

解决方案


您可以使用 map 创建一个组数组 (employeeProjectIds) 并使用该数组将数组缩减为组。

我有一种感觉,employee_project因为开始、结束日期和分配对于员工和项目来说都是独一无二的,所以也需要合并中的字段。

然后在合并数据中映射组数组:

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)
  )
)

可能有一些您不熟悉的语法,例如在对象字面量中传播以复制对象(不是深拷贝)、箭头函数和在尝试查找数组中的元素时使用的解构赋值。

map 和 reduce 方法记录在这里


推荐阅读