0

I need to get the expectedOutput array, which consists of the objects with the higher amount number. This code concat the two arrays and then reduce by higher amount. Im looking for a better way to do this, without concat. Thanks in advance.

let arr1 = [{name: 'Almendras', amount: 0},{name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 0}];
let arr2 = [{name: 'Almendras', amount: 2}];

let expectedOutput = [{name: 'Almendras', amount: 2}, {name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 0}];

let concat = arr1.concat(arr2);

const output = Object.values(concat.reduce((x, y) => {
  x[y.name] = x[y.name] && x[y.name].amount > y.amount ? x[y.amount] : y
  return x
}, {}));

console.log(output);
sonEtLumiere
  • 4,461
  • 3
  • 8
  • 35
  • Does this answer your question? [Merge two array of objects based on a key](https://stackoverflow.com/questions/46849286/merge-two-array-of-objects-based-on-a-key) – Heretic Monkey Jul 14 '20 at 19:39
  • no, i dont need to merge arrays – sonEtLumiere Jul 14 '20 at 19:47
  • ...So what's `arr1` and `arr2` in your example code? – Heretic Monkey Jul 14 '20 at 19:49
  • Does the end result need to be a sorted array? Could it be an object as well? – Narigo Jul 14 '20 at 19:49
  • "*without concat.*" - what's wrong with that? – Bergi Jul 14 '20 at 19:51
  • Add into your question why you want to avoid concatenating the arrays, preferably with a concrete example. You should have a good reason for it, and said reason will affect the answer. It is likely that your concern is not important, you are misunderstanding the issues related to your question, and/or there is a better solution to your problem. – user120242 Jul 14 '20 at 19:52
  • 1
    Your current code produces weird output if you swap the `amount` of the "Almendras" objects due to the expression `x[y.amount]` this should just be `x`. – 3limin4t0r Jul 14 '20 at 19:52
  • Its for prevent bugs, sometimes arr2 is an empty array – sonEtLumiere Jul 14 '20 at 19:55
  • 1
    @sonEtLumiere But `concat` handles empty arrays just fine. What bug are you referring to? Can you please post the input for the buggy case, where your code does not work as expected? – Bergi Jul 14 '20 at 19:58
  • 1
    @sonEtLumiere empty arrays concat just fine though? and even then you could just check arr2.length or typeof? – user120242 Jul 14 '20 at 19:58

1 Answers1

4

You can avoid the concat call by running the reduce on both arrays individually:

let arr1 = [{name: 'Almendras', amount: 0},{name: 'Nueces', amount: 0}, {name: 'Chocolate', amount: 0}];
let arr2 = [{name: 'Almendras', amount: 2}];

function mergeHigher(acc, el) {
  const old = acc[el.name];
  if (!old || el.amount >= old.amount) acc[el.name] = el;
  return acc;
}

const out1 = arr1.reduce(mergeHigher, {});
const out2 = arr2.reduce(mergeHigher, out1);

console.log(Object.values(out2));
Bergi
  • 630,263
  • 148
  • 957
  • 1,375