Skip to content

Got undefined in map result

I’m having trouble converting, summing, and sorting the following arrays into key and value objects

Data Array

0: {No: '1', Product Name: 'Harry Potter', Type: 'Novel', Price: '120', Url: 'https://harry-potter'}
1: {No: '2', Product Name: 'Harry Potter', Type: 'Novel', Price: '100', Url: 'https://harry-potter'}
2: {No: '3', Product Name: 'Naruto', Type: 'Comic', Price: '68', Url: 'https://naruto'}
n: {No: '...', Product Name: '...', Type: '...', Price: '...', Url: '...'}

my current code

let counts = myRows.reduce((prev, curr) => {
  let count = prev.get(curr["Product Name"]) || 0;
  prev.set(
    curr["Product Name"],
    parseFloat(curr["Product Name"]) + count,
    curr["Url"]
  );
  return prev;
}, new Map());

// then, map your counts object back to an array
let reducedObjArr = [...counts].map(([key, value, link]) => {
  return { key, value, link };
});

// SORT BY DESCENDING VALUE
var desc = reducedObjArr.sort((a, b) => b.value - a.value);

console.log(desc);

and the result of my current code

0:
key: "Harry Potter"
link: undefined
value: 220
1:
key: "Naruto"
link: undefined
value: 68

though, the result I want is like this

0:
key: "Harry Potter"
link: "https://harry-potter"
value: 220
1:
key: "Naruto"
link: "https://naruto"
value: 68

Answer

Map.prototype.set() only takes 2 arguments, you’re passing 3. If you want to store multiple values in a map key, store them as an array or object. In my code below, I store [price, url].

Another problem is that you were trying to parse curr["Product Name"] as the price, but it should be curr.Price.

const myRows = [
  {No: '1', "Product Name": 'Harry Potter', Type: 'Novel', Price: '120', Url: 'https://harry-potter'},
  {No: '2', "Product Name": 'Harry Potter', Type: 'Novel', Price: '100', Url: 'https://harry-potter'},
  {No: '3', "Product Name": 'Naruto', Type: 'Comic', Price: '68', Url: 'https://naruto'}
];

let counts = myRows.reduce((prev, curr) => {
  let count = prev.get(curr["Product Name"])?.[0] || 0;
  prev.set(
    curr["Product Name"], 
    [parseFloat(curr.Price) + count,
      curr.Url
    ]
  );
  return prev;
}, new Map());

// then, map your counts object back to an array
let reducedObjArr = [...counts].map(([key, [value, link]]) => {
  return {
    key,
    value,
    link
  };
});

// SORT BY DESCENDING VALUE
var desc = reducedObjArr.sort((a, b) => b.value - a.value);

console.log(desc);