Javascript 合并阵列中的重复对象并合并每个对象的子阵列

Javascript 合并阵列中的重复对象并合并每个对象的子阵列,javascript,array-merge,Javascript,Array Merge,我试图根据Id合并对象,并合并每个帐户(对象)中的每个数组,但如果存在匹配的Id,代码将覆盖数组,而不是合并accountList的内容 我创建了一个新数组,并使用.find方法根据该id查找匹配的对象,但仍停留在如何将accountList合并在一起的问题上 const accounts = [ { "Id": 103, "accountList": [ {} ] }, { "Id": 103, "accountList":

我试图根据Id合并对象,并合并每个
帐户
(对象)中的每个数组,但如果存在匹配的Id,代码将覆盖数组,而不是合并accountList的内容

我创建了一个新数组,并使用.find方法根据该id查找匹配的对象,但仍停留在如何将
accountList
合并在一起的问题上

const accounts = [
    {
    "Id": 103,
    "accountList": [
      {}
    ]
  },
  {
    "Id": 103,
    "accountList": [
      {
        "tokenId": "5aasdasdsdnjn3434nadd",
        "featureId": 2840
      }
    ]
  },
  {
    "Id": 112,
    "accountList": [
      {
        "tokenId": "5d30775bef4a722c38aefaaa",
        "featureId": 2877
      }
    ]
  },
    {
    "Id": 112,
    "accountList": [
      {
        "tokenId": "5d30775bef4a722c38aefccc",
        "featureId": 2856
      }
    ]
  }
]

console.log(JSON.stringify(result,null,2))

我需要的结果是根据对象的id合并对象,并将
accountList
的内容合并在一起,如下所示:

[
  {
    "Id": 103,
    "accountList": [
      {
        "tokenId": "5aasdasdsdnjn3434nadd",
        "featureId": 2840
      }
    ]
  },
  {
    "Id": 112,
    "accountList": [
      {
        "tokenId": "5d30775bef4a722c38aefaaa",
        "featureId": 2877
      },
      {
        "tokenId": "5d30775bef4a722c38aefccc",
        "featureId": 2856
      }
    ]
  }
]

我想你可以使用
match.accountList.push(…account.accountList)而不是对象分配,可以使用排列运算符将元素推入结果项(
match
):

let accounts=[{“Id”:103,“accountList”:[{},{“Id”:103,“accountList”:[{“tokenId”:“5aasdsdsdnjn3434nadd”,“featureId”:2840},{“Id”:112,“accountList”:[{“tokenId”:“5d30775bef4a722c38aefaaa”,“featureId”:2877},{“Id”:112,“accountList”:[{“tokenId”:“5d3075bef4a722c38aefccc”,“featureId”:2856}];
让结果=[];
accounts.forEach(account=>{
(match=result.find(r=>r.Id==account.Id),match?match.accountList.push(…account.accountList):result.push(account))
});

控制台日志(结果)使用
Array.prototype.reduce
我们可以在最终的
结果
数组中累积结果

在reduce回调中,只需使用Id找到匹配的对象,然后合并
accountList
数组,而不是像在代码中那样合并对象

const accounts=[{“Id”:103,“accountList”:[{}},{“Id”:103,“accountList”:[{“tokenId”:“5aasdsdnjn3434nadd”,“featureId”:2840}},{“Id”:112,“accountList”:[{“tokenId”:“5d3075bef4a722c38aefaaa”,“featureId”:2877},{“Id”:112,“accountList”:[{“tokenId”:“5d3075bef4a722c38aefccc”,“featureId”:2856}];
const result=账户。reduce((acc,账户)=>{
让match=acc.find(r=>r.Id==account.Id);
如果(匹配){
match.accountList.push(…account.accountList);//推送上一个数组
}否则{
const act={…account};
act.accountList=account.accountList.filter((obj)=>Object.keys(obj.length);
acc.push(act);
}
返回acc;
}, []);
控制台日志(结果)我认为,
reduce()
可以完成这项工作:

const accounts=[{“Id”:103,“accountList”:[{}},{“Id”:103,“accountList”:[{“tokenId”:“5aasdsdnjn3434nadd”,“featureId”:2840}},{“Id”:112,“accountList”:[{“tokenId”:“5d3075bef4a722c38aefaaa”,“featureId”:2877},{“Id”:112,“accountList”:[{“tokenId”:“5d3075bef4a722c38aefccc”,“featureId”:2856}];
const result=[…帐户
.减少((r,o)=>{
const record=r.get(o.Id)| |{
r、 设置(o.Id{
Id:o.Id,
帐户列表:[
…(record.accountList | |[]),
…o.accountList.filter(o=>
Object.keys(o).length!=0)
]            
})
返回r
},新映射())
.values()]
控制台日志(结果)
。作为控制台包装{min height:100%}
您可以尝试使用:


这将合并具有相同ID的所有帐户。希望这有帮助:)

但是如果accountlist:{}它也可以pushed@RakibulIslam:根据OP的示例,情况似乎并非如此。啊,对不起,我单击了错误的oneNo,我很乐意提供帮助。我更新了代码,最初还包括了空对象。这个问题现在已经解决了。我的错。感谢所有帮助过我的人:)
[
  {
    "Id": 103,
    "accountList": [
      {
        "tokenId": "5aasdasdsdnjn3434nadd",
        "featureId": 2840
      }
    ]
  },
  {
    "Id": 112,
    "accountList": [
      {
        "tokenId": "5d30775bef4a722c38aefaaa",
        "featureId": 2877
      },
      {
        "tokenId": "5d30775bef4a722c38aefccc",
        "featureId": 2856
      }
    ]
  }
]
    let result = [];
    accounts.forEach(account => {
      let match = result.find(r => r.Id === account.Id);
      // console.log(match)
      if(match) {
        match.accountList = match.accountList.concat(account.accountList);
      } else {
        result.push(account);
      }
    });

for (let res of result) {
  console.log('res.Id: ', res.Id, res.accountList)
}

// res.Id:  103 [ {}, { tokenId: '5aasdasdsdnjn3434nadd', featureId: 2840 } ]
// res.Id:  112 [ { tokenId: '5d30775bef4a722c38aefaaa', featureId: 2877 },
//   { tokenId: '5d30775bef4a722c38aefccc', featureId: 2856 } ]
const isNotEmptyObject = objc => Object.entries(objc).length > 0;

function mergeAccounts(accounts) {
    const uniqueAccounts = new Map();
    accounts.forEach(account => {
        if(uniqueAccounts.has(account.Id)) {
            let uniqueAccount = uniqueAccounts.get(account.Id);
            if(account.accountList && account.accountList.length > 0)
                uniqueAccount.accountList.push(...account.accountList);
                uniqueAccount.accountList = uniqueAccount.accountList.filter(isNotEmptyObject);
        } else {
            uniqueAccounts.set(account.Id, account);
        }
    });
  return Array.from(uniqueAccounts.values());
}