0

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!

2
  • What about sorting first and then slicing? Commented Jan 13, 2021 at 17:15
  • arrOfObjs.sort((a, b) => b.number - a.number).slice(0, 5) Commented Jan 13, 2021 at 17:17

3 Answers 3

1

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)

Sign up to request clarification or add additional context in comments.

Comments

1

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]
   );
}

1 Comment

Please consider this answer, moving the Math.max calculation out of the findIndex callback, as you don't want to repeat the very same call over and over again as in the accepted answer... It makes it very inefficient.
0

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))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.