Milos
Milos

Reputation: 619

Find 5 largest numbers in array of objects and push it to another array

I have an array of objects and I want to find the five biggest numbers in object values and to push these five objects to the new array, but also remove them from the first array. I've tried using for loop combined with push and splice methods, but the result is kind of weird. Here is an example of what I've tried

const arrOfObjs = [
    {number: 1, bla: 'sadsad'},
  {number: 2, bla: 'sadsad'},
  {number: 3, bla: 'sadsad'},
  {number: 9, bla: 'sadsad'},
  {number: 4, bla: 'sadsad'},
  {number: 10, bla: 'sadsad'},
  {number: 5, bla: 'sadsad'},
  {number: 6, bla: 'sadsad'},
  {number: 7, bla: 'sadsad'},
  {number: 8, bla: 'sadsad'},
]

let largestNumbers = [];

for(var i=0; i<5; i++) {
  largestNumbers.push(
    arrOfObjs.splice(
      arrOfObjs.indexOf(
        Math.max.apply(
          Math,arrOfObjs.map(function(o){
            return o.number;
          })
        )
      ), 1)[0])
}

console.log(largestNumbers)

Everything seems to be working instead of the final result, which should be

[{
  bla: "sadsad",
  number: 8
 }, {
  bla: "sadsad",
  number: 7
 }, {
  bla: "sadsad",
  number: 6
 }, {
  bla: "sadsad",
  number: 9
 }, {
  bla: "sadsad",
  number: 10
}]

I'm not sure why number 9 isn't returned, and why the number 5 is. What am I doing wrong? Thanks in advance!

Upvotes: 0

Views: 113

Answers (3)

trincot
trincot

Reputation: 350756

The error is in the indexOf part. You will not find the maximum value, because your array has objects (with number property that should be compared instead). So replace

arrOfObjs.indexOf(Math.max ........)

with:

arrOfObjs.findIndex(o => o.number === max)

... where max is the Math.max expression, which you should then do separately, like this:

for(var i=0; i<5; i++) {
   let max = Math.max.apply(
      Math,
      arrOfObjs.map(o => o.number)
   );
   largestNumbers.push(arrOfObjs.splice(
      arrOfObjs.findIndex(o => o.number === max), 1)[0]
   );
}

Upvotes: 1

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196197

The problem is that you do .indexOf on an array with objects using an integer as the parameter.

Try .findIndex(({number})=>number === Math.max.apply ...

const arrOfObjs = [
  {number: 1, bla: 'sadsad'},
  {number: 2, bla: 'sadsad'},
  {number: 3, bla: 'sadsad'},
  {number: 9, bla: 'sadsad'},
  {number: 4, bla: 'sadsad'},
  {number: 10, bla: 'sadsad'},
  {number: 5, bla: 'sadsad'},
  {number: 6, bla: 'sadsad'},
  {number: 7, bla: 'sadsad'},
  {number: 8, bla: 'sadsad'},
]
let largestNumbers = [];

for (var i = 0; i < 5; i++) {
  largestNumbers.push(
    arrOfObjs.splice(
      arrOfObjs.findIndex(({
          number
        }) => number ===
        Math.max.apply(
          Math, arrOfObjs.map(function(o) {
            return o.number;
          })
        )
      ), 1)[0])
}

console.log(largestNumbers)

Upvotes: 1

ptothep
ptothep

Reputation: 395

I would sort it and then slice it.

const arrOfObjs = [
    {number: 1, bla: 'sadsad'},
  {number: 2, bla: 'sadsad'},
  {number: 3, bla: 'sadsad'},
  {number: 9, bla: 'sadsad'},
  {number: 4, bla: 'sadsad'},
  {number: 10, bla: 'sadsad'},
  {number: 5, bla: 'sadsad'},
  {number: 6, bla: 'sadsad'},
  {number: 7, bla: 'sadsad'},
  {number: 8, bla: 'sadsad'},
]

console.log(arrOfObjs.sort((a,b)=> a.number - b.number).slice(-5))

Upvotes: 0

Related Questions