Sort, slice and rebuild new object with array data I'm using the matomo reports api to pull out some data in js.
For some charts, I'm in the need to sort the array data based on inner property value ("val"), further to get only the 3 highest (Hong Kooong, Munich, Tokyo). Finally, this data should be used for the creation of a new key/val object (newObj).

This is what my code looks like what does what it should. I would be interested if it can be optimized using es6 syntax.



    let data = {
      0 : {"label":"New York", "val": 20},
      1 : {"label":"Rio", "val": 10},
      3 : {"label":"Tokyo", "val": 50},
      4 : {"label":"Santiago", "val": 20},
      5 : {"label":"Hong Kooong", "val": 100},
      6 : {"label":"Munich", "val": 90},
    }
    
    let compare = (a, b)  =&gt; {
      let valA = a.val;
      let valB = b.val;
      let c = 0;
    
      if (valA &gt; valB) {
        c = 1;
      } else if (valA &lt; valB) {
        c = -1;
      }
      return c * -1;
    }
    
    let dataArray = Object.values(data).sort(compare)
    dataArray = dataArray.slice(0, 3)
    
    let newLabel = []
    let newValue = []
    Object.keys(dataArray).map(function(key, index) {
      newLabel.push(dataArray[index]['label'])
      newValue.push(dataArray[index]['val'])
    });
    
    let newObj = {}
    newObj.data = {}
    newObj.data.labels = newLabel
    newObj.data.values = newValue
    
    console.log(newObj)
Let's start with how I would have done it.



const data = {
  0 : {"label":"New York", "val": 20},
  1 : {"label":"Rio", "val": 10},
  3 : {"label":"Tokyo", "val": 50},
  4 : {"label":"Santiago", "val": 20},
  5 : {"label":"Hong Kooong", "val": 100},
  6 : {"label":"Munich", "val": 90},
}

const result = Object.values(data)
  .sort((a, b) =&gt; b.val - a.val)
  .slice(0, 3)
  .reduce((c, v) =&gt; {
    c.data.labels.push(v.label)
    c.data.values.push(v.val)
    return c
  }, { data: { labels: [], values: []}})
  
console.log(result)




Now onto your code:

let dataArray = Object.values(data).sort(compare)
dataArray = dataArray.slice(0, 3)


You were off to a good start here. One minor nitpick is to just chain the operations since you're just reassigning dataArray with sort's results.

let newLabel = []
let newValue = []
Object.keys(dataArray).map(function(key, index) {
  newLabel.push(dataArray[index]['label'])
  newValue.push(dataArray[index]['val'])
});

let newObj = {}
newObj.data = {}
newObj.data.labels = newLabel
newObj.data.values = newValue


This is where it went crazy.

Firstly, you used Object.keys() on dataArray (an array), which is not needed. If you need the array item index, all of the array methods provide the item index as second argument of the callback.

Also, this is a bad use of array.map(). array.map() is used to transform values in one array to another array of values, i.e. a 1:1 transform operation. In this case, you're merely using it for looping, something better suited for array.forEach().

Since you're "reducing"/"aggregating" an array of values into one value (turning an array of values into an object), array.reduce() is the better option.