-3

I wanna sort this array in ascending order based on the max ranking in the objects, but there are certain objects that have null values for ranking , I want to throw the objects with null at the end, here is what I tried but it's not working , when I am logging the first 10 ranks of the sorted array I still have undefined values

async function getLive(){
    let response= await fetch('https://tennisapi1.p.rapidapi.com/api/tennis/events/live', options)
    let json= await response.json()
    for(let i=0; i<10;i++){
        console.log(json.events[i].awayTeam.ranking<json.events[i].homeTeam.ranking?json.events[i].awayTeam.ranking:json.events[i].homeTeam.ranking)
    }
    json.events.sort((a, b) => {
      let x=1000000  
      let r1 = Math.min(a.awayTeam.ranking , a.homeTeam.ranking)
          
      if(r1===null){
        r1=x
      }
      x+=1
      let r2 = b.awayTeam.ranking < b.homeTeam.ranking ? b.awayTeam.ranking : b.homeTeam.ranking;
      if(r2===null){
        r2=x
      }
      x++
      return r1 - r2;
    });
    live=json.events
    console.log('-----------------------------')
    for(let i=0; i<10;i++){
        console.log(Math.min(live[i].awayTeam.ranking ,live[i].homeTeam.ranking))
    }

when I log here is what I get, why are the Nan values there it makes no sense

121 NaN NaN 73 192 295 360 394 473 475

w4ss
  • 45
  • 4
  • Could you please show what the fetch response is? If this is a public API, please show the `options` object so we can reproduce this. – Chris Hamilton Mar 29 '23 at 15:50
  • Please also explain how the sort should work, and what you're doing with x=1000000 etc. The whole sort function can probably be simplified considerably. – Andrew Parks Mar 29 '23 at 15:57
  • or [Sort an array of numbers so that null values come last](https://stackoverflow.com/questions/43819867/sort-an-array-of-numbers-so-that-null-values-come-last) – pilchard Mar 29 '23 at 15:58

3 Answers3

2

There is a neat trick to make this simple. You can just coalesce null values as -Infinity!

values.sort(
    (a, b) => (b ?? -Infinity) - (a ?? -Infinity)
);

This way, any null (or undefined) value will be replaced by the smallest possible value, hence it goes to the very end of the array.

Robo Robok
  • 21,132
  • 17
  • 68
  • 126
  • covered in the [duplicate](https://stackoverflow.com/a/58748962/13762301) (though pre nullish coallescing) Made a note on that answer to update it. – pilchard Mar 29 '23 at 16:06
1

I don't know what your data looks like, but here is an example with a simple array:

const array = [1, 4, 6, 2, 7, null, 2, 5, 10, null, 3]

array.sort((a, b) => {
  if (a === b) return 0
  if (a === null) return 1
  if (b === null) return -1
  return a - b
})

console.log(array)
Konrad
  • 21,590
  • 4
  • 28
  • 64
1

An alternative solution would be to first partition the array into "rated" and "unrated" items based on whether rating is null, then sort the rated items, and finally concatenating the two using the spread operator:

const array = [
  {rating: 66},
  {rating: null},
  {rating: 42},
  {rating: 101},
]
const rated = array.filter(x => x.rating !== null)
const unrated = array.filter(x => x.rating === null)
rated.sort((a, b) => a.rating - b.rating)
const sorted = [...rated, ...unrated] // alternatively you could also append unrated to rated after sorting if you don't want to copy rated here
console.log(sorted)
Luatic
  • 8,513
  • 2
  • 13
  • 34