2
votes

Comment fusionner 2 tableaux en fonction d'un nom de clé et trier en fonction de la valeur fusionnée?

Supposons que j'ai deux listes

sortListDesc(list) {

    return obj.sort(function (l1,l2) {
      return l2< l1 ? -1
           : l2 >l1 ? 1
           : 0
    })
  }

La question est de savoir comment fusionner deux listes en une seule pile du même élément avec un incrément de nombre et trier par quantité? Je veux dire que le résultat final devrait être ->

const listMerged = [{"apple":115}, {"banana": 50} , {"peach": 30}, {"kiwi": 13}, {"pearl": 10}, {"cherry": 5}, {"mango": 5}]

Je sais que ça va être quelque chose comme:

const listA = [{"apple":100}, {"banana": 50}, {"pearl": 10}, {"cherry": 5}, {"kiwi": 3}]
const listB = [{"peach": 30}, {"apple": 15}, {"kiwi": 10}, {"mango": 5}]

mais fais ne sais pas exactement comment empiler le nombre, que de trier par nombre de quantité.


2 commentaires

Pour le tri - renvoie Object.values ​​(l1) [0] -Object.values ​​(l2) [0]


duplication possible stackoverflow. com / questions / 42488048 /…


3 Réponses :


1
votes

Vous pouvez parcourir la deuxième liste en utilisant forEach et vérifier si le même élément est présent dans la première liste en utilisant findIndex . Si l'élément n'est pas présent (-1), poussez l'élément dans la première liste. S'il est présent, utilisez l'index pour récupérer cet objet, puis mettre à jour sa valeur dans un for..in

const listA = [{
  "apple": 100
}, {
  "banana": 50
}, {
  "pearl": 10
}, {
  "cherry": 5
}, {
  "kiwi": 3
}]
const listB = [{
  "peach": 30
}, {
  "apple": 15
}, {
  "kiwi": 10
}, {
  "mango": 5
}]
let newArr = listB.forEach((item) => {
  let ifElemPresentInListA = listA.findIndex((elem) => {
    return Object.keys(elem)[0] === Object.keys(item)[0]

  })

  if (ifElemPresentInListA === -1) {
    listA.push(item)
  } else {
    for (let keys in listA[ifElemPresentInListA]) {
      listA[ifElemPresentInListA][keys] += Object.values(item)[0]
    }
  }

})

console.log(listA)


0 commentaires

2
votes

Vous pouvez utiliser réduire et sort et Object.values ​​ comme ceci:

const listA = [{"apple":100}, {"banana": 50}, {"pearl": 10}, {"cherry": 5}, {"kiwi": 3}]
, listB = [{"peach": 30}, {"apple": 15}, {"kiwi": 10}, {"mango": 5}]

let merged2 = listA.concat(listB).reduce((acc, a) => {
  const [k, v] = Object.entries(a)[0];
  acc[k] = (acc[k] || 0) + v;
  return acc;
}, {});

const final = Object.entries(merged2)
  .sort(([, v1], [, v2]) => v2 - v1)
  .map(([k, v]) => ({[k]: v}))

console.log(final);

Ou,

En utilisant réduire , créez un objet avec tous les fruits comme clés et une somme individuelle comme valeurs. Utilisez ensuite Object.entries code> , tri et map comme ceci:

const listA = [{"apple":100}, {"banana": 50}, {"pearl": 10}, {"cherry": 5}, {"kiwi": 3}]
, listB = [{"peach": 30}, {"apple": 15}, {"kiwi": 10}, {"mango": 5}]

let merged = Object.values(listA.concat(listB).reduce((acc, a) => {
  const [k, v] = Object.entries(a)[0];
  (acc[k] = acc[k] || {[k]: 0})[k] += v;
  return acc;
}, {}));

merged.sort((a, b) => Object.values(b)[0] - Object.values(a)[0]);
console.log(merged);


0 commentaires

1
votes

Je pense que j'ai un code légèrement plus propre que celui de brk

const listA = [{"apple":100}, {"banana": 50}, {"pearl": 10}, {"cherry": 5}, {"kiwi": 3}]
const listB = [{"peach": 30}, {"apple": 15}, {"kiwi": 10}, {"mango": 5}]

const both = Object.assign({}, ... listA, ... listB); // concatenate both lists and convert them to an object
const lA = Object.assign({}, ...listA); // convert listA to an object
const lB = Object.assign({}, ...listB);

var result = Object.keys(both).map( (a) => { // mapping sums the values and yields an array
  var sum = {};
  sum [a] =(lA[a] ? lA[a] : 0) + (lB[a] ? lB[a] : 0);
  return sum;
});
// sorting in desc order (hence b - a ) based on values (hence b[Object.keys(b)]) rather than keys
result.sort((a,b) => b[Object.keys(b)] - a[Object.keys(a)] ); 

La complexité est due au fait que vous stockez les valeurs sous forme de tableau. Je pense que ce n'est pas la meilleure façon de l'avoir car le tableau peut avoir plusieurs éléments avec les mêmes clés. Par exemple. vous pouvez vous retrouver avec quelque chose comme ça: const listA = [{"apple": 100}, ..., {"apple": 10}] qui est valide mais peut poser un problème. Je vous suggère d'envisager de l'utiliser comme un objet, par exemple: const listA = {{'apple': 100}, {'banana': 50}} cela simplifiera considérablement le code et évitera les doublons

J'espère que cela vous aidera!


0 commentaires