2
votes

fusionner les objets en double dans un tableau et combiner le sous-tableau de chaque objet

J'essaye de fusionner des objets basés sur Id, et de fusionner chaque tableau qui vit à l'intérieur de chaque compte (objet), mais au lieu de fusionner le contenu de accountList, le code écrase le tableau, si il y a un identifiant correspondant.

J'ai créé un nouveau tableau et utilisé la méthode .find pour trouver les objets correspondants en fonction de leur identifiant, mais je suis resté coincé sur la façon de fusionner la accountList ensemble p >

[
  {
    "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) {
   Object.assign(match, account);
    //tried using spread operator instead of object assign, but didnt work
    //  match = {...match, ...account}
  } else {
    result.push(account);
  }
});

console.log (JSON.stringify (résultat, null, 2))

Le le résultat dont j'ai besoin est de fusionner l'objet en fonction de son identifiant et de fusionner le contenu de la accountList ensemble, comme ceci:

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


4 commentaires

ahh désolé j'ai cliqué sur le mauvais


Pas de soucis, j'étais heureux d'aider.


J'ai mis à jour mon code, initialement l'objet vide était également inclus. Ceci est maintenant réparé. Ma faute.


Merci à tous ceux qui ont aidé :)


5 Réponses :


0
votes

Je pense que vous pouvez utiliser match.accountList.push (... account.accountList); au lieu de l'attribution d'objet, l'opérateur de propagation peut être utilisé pour pousser l'élément dans l'élément de résultat ( match ):

let 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 }] }];
let result = [];
accounts.forEach(account => {
  (match = result.find(r => r.Id === account.Id), match ? match.accountList.push(...account.accountList) : result.push(account))
});
console.log(result);


0 commentaires

1
votes

En utilisant Array.prototype.reduce , nous pouvons accumuler les résultats dans le tableau result final.

Dans le rappel de réduction, trouvez simplement l'objet correspondant en utilisant Id et fusionnez le tableau accountList et non l'objet comme vous le faisiez dans votre code.

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}]}];

const result = accounts.reduce((acc, account) => {
     let match = acc.find(r => r.Id === account.Id);
     if(match) {
       match.accountList.push(...account.accountList); //push previous array
     } else {
       const act = { ...account }; 
       act.accountList = account.accountList.filter((obj) => Object.keys(obj).length);
       acc.push(act);
     }
     return acc;
}, []);
console.log(result);


0 commentaires

1
votes

Je pense que reduction () ferait l'affaire:

.as-console-wrapper {min-height: 100%}
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}]}];

const result = [...accounts
        .reduce((r, o) => {
          const record = r.get(o.Id)||{}
          r.set(o.Id, {
            Id: o.Id,
            accountList: [
              ...(record.accountList||[]),
              ...o.accountList.filter(o => 
                Object.keys(o).length != 0)
            ]            
          })
          return r
        }, new Map())
        .values()]

console.log(result);


2 commentaires

mais si la liste de comptes: {} elle a également poussé


@RakibulIslam: Cela ne semble pas être le cas selon l'exemple d'OP.



0
votes

Vous pouvez essayer d'utiliser Array. concat :

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


0 commentaires

0
votes
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());
}

This will merge all the accounts having same ids. Hope this helps :)

0 commentaires