如何在Javascript中映射数组一对多关系

Posted

技术标签:

【中文标题】如何在Javascript中映射数组一对多关系【英文标题】:How to map array one to many relationship in Javascript 【发布时间】:2020-07-24 08:01:55 【问题描述】:

我正在尝试使用 map 函数将以下 JSON 数据转换为适当的输出

["jobId":100049,"name":"Drilling","jobNumber":"1222455","address":"Ahmedabad","city":"Ahmedabad","state":"1","zip":"38003","active":true,"jobOwnerId":100002,"jobOwnerName":"Troy Thomson","createdBy":"","createdOn":"2020-03-15T18:42:25.6533333","modifiedBy":"","modifiedOn":"2020-03-16T13:21:53.0333333","members":["memberId":100001,"memberName":"Hardik Gondalia","memberId":100004,"memberName":"Micheal T. Angelo"],"assets":["assetId":100004,"assetName":"Minima ullam non mol"],"jobId":100051,"name":"Drilling The Hole","jobNumber":"11111","address":"201, AA 333 Steet, Time Square","city":"Boston","state":"1","zip":"11111","active":true,"jobOwnerId":100001,"jobOwnerName":"Hardik Gondalia","createdBy":"","createdOn":"2020-03-25T11:12:13.89","modifiedBy":"","modifiedOn":"2020-03-25T11:12:32.1266667","members":["memberId":100002,"memberName":"Troy Thomson"],"assets":["assetId":100005,"assetName":"Drill Machine P2222"]]

期望的输出:

["jobid":100049,"memberid":100001],"jobid":100049,"memberid":100004],"jobid":100051,"memberid":100002]

如您所见,job 是 json 对象,其中包含成员和资产数组。如果它有多个成员或资产,我想重复 jobid。

我试过的是:

const assignmentAssetModel = this.jobList.map(i => ( jobid: i.jobId, assetid: i.assets.map(j => j.assetId) ));

但它给了我以下输出:

["jobid":100049,"memberid":[100001,100004],"jobid":100051,"memberid":[100002]]

如果你有多个 memberid,我想重复 jobid

【问题讨论】:

【参考方案1】:

您可以使用Array#flatMap 并映射外部和内部属性。

var data = [ jobId: 100049, name: "Drilling", jobNumber: "1222455", address: "Ahmedabad", city: "Ahmedabad", state: "1", zip: "38003", active: true, jobOwnerId: 100002, jobOwnerName: "Troy Thomson", createdBy: "", createdOn: "2020-03-15T18:42:25.6533333", modifiedBy: "", modifiedOn: "2020-03-16T13:21:53.0333333", members: [ memberId: 100001, memberName: "Hardik Gondalia" ,  memberId: 100004, memberName: "Micheal T. Angelo" ], assets: [ assetId: 100004, assetName: "Minima ullam non mol" ] ,  jobId: 100051, name: "Drilling The Hole", jobNumber: "11111", address: "201, AA 333 Steet, Time Square", city: "Boston", state: "1", zip: "11111", active: true, jobOwnerId: 100001, jobOwnerName: "Hardik Gondalia", createdBy: "", createdOn: "2020-03-25T11:12:13.89", modifiedBy: "", modifiedOn: "2020-03-25T11:12:32.1266667", members: [ memberId: 100002, memberName: "Troy Thomson" ], assets: [ assetId: 100005, assetName: "Drill Machine P2222" ] ],
    result = data.flatMap(( jobId, members ) =>
        members.map(( memberId ) => ( jobId, memberId )));

console.log(result);
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

【参考方案2】:

您可以使用Array.reduce() 代替Array.map(),因为结果数组的长度与初始数组的长度不同。

const jobList = ["jobId":100049,"name":"Drilling","jobNumber":"1222455","address":"Ahmedabad","city":"Ahmedabad","state":"1","zip":"38003","active":true,"jobOwnerId":100002,"jobOwnerName":"Troy Thomson","createdBy":"","createdOn":"2020-03-15T18:42:25.6533333","modifiedBy":"","modifiedOn":"2020-03-16T13:21:53.0333333","members":["memberId":100001,"memberName":"Hardik Gondalia","memberId":100004,"memberName":"Micheal T. Angelo"],"assets":["assetId":100004,"assetName":"Minima ullam non mol"],"jobId":100051,"name":"Drilling The Hole","jobNumber":"11111","address":"201, AA 333 Steet, Time Square","city":"Boston","state":"1","zip":"11111","active":true,"jobOwnerId":100001,"jobOwnerName":"Hardik Gondalia","createdBy":"","createdOn":"2020-03-25T11:12:13.89","modifiedBy":"","modifiedOn":"2020-03-25T11:12:32.1266667","members":["memberId":100002,"memberName":"Troy Thomson"],"assets":["assetId":100005,"assetName":"Drill Machine P2222"]]


const jobsPerMember = jobList.reduce((acc, cur) => 
  cur.members.forEach((member) => acc.push(
      jobid: cur.jobId,
      memberid: member.memberId
  ))
  return acc
,[])

console.log(jobsPerMember)

【讨论】:

【参考方案3】:

您应该改用.reduce 方法:

this.jobList.reduce((acc,  members, jobId ) => 
   return [...acc, ...members.map(( memberId ) => ( jobId, memberId ))]; 
, []);

如果您的目标是更新版本的 javascript (ES2019),您也可以使用 flatMap:

this.jobList.flatMap(( members, jobId ) => members.map(( memberId ) => ( jobId, memberId )));

【讨论】:

以上是关于如何在Javascript中映射数组一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

如何使用自定义映射映射一对多关系

Java中一对多映射关系

Java中一对多映射关系(转)

MyBatis的一对一关联关系映射

MyBatis的一对一关联关系映射

当关联表是一个对所有一对多关系时,如何实现一对多映射?