2

I'm using the Javascript sorting to sort an array of objects. This is why i'm trying to do (take the 10 best players in my array) :

      this.topPlayers .sort(function(a, b) {
        return a.stars > b.stars;
      });
      this.topPlayers = this.topPlayers.slice(0,10);

It returns me the same thing when i'm doing this (the 10 worst players) :

      this.topPlayers .sort(function(a, b) {
        return a.stars < b.stars;
      });
      this.topPlayers = this.topPlayers.slice(0,10);

What am I doing wrong ? Same results in both case, tried to sort on other properties, again same result... I'm using angular and doing it on ngOnInit() function.

Thibault Dumas
  • 1,060
  • 2
  • 10
  • 21
  • Can you provide sample input and the exact output for each case? I just tested the sort callbacks you wrote, and it should be working. – Evan Bechtol Sep 21 '20 at 15:44
  • There's a space between `this.topPlayers` and `.sort(`. I'm sure that's a transcription error, but thought I'd point it out. – Griffin Sep 21 '20 at 15:44
  • what is `a.stars` type value ? string, number ? date ? object? array ? – Mister Jojo Sep 21 '20 at 15:45
  • 1
    use `return a.stars - b.stars` or `return b.stars - a.stars` – sandeep joshi Sep 21 '20 at 15:49
  • 1
    I added an answer (along with two other people at the same time, hah). But I have to point out that you could have very easily answered your own question by referring to MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort You clearly just assumed you knew how Array.sort worked without looking it up. – Griffin Sep 21 '20 at 15:53

3 Answers3

3

Your compare function is returning a boolean. Array.sort() expects you to return a number.

If your compare functions returns a value < 0, 'a' will be placed before 'b'.

If your compare functions returns a value > 0, 'b' will be placed before 'a'.

If your compare functions returns 0, the order will remain as-is.

So, to sort by number of stars in descending order, you could do this:

this.topPlayers.sort((a, b) => b.stars - a.stars);

If 'a' has more stars than 'b', the return value will be negative, and 'a' will be sorted before 'b', and vice versa.

Griffin
  • 196
  • 2
  • 8
2

This is because Array's sort() expects it's function to return a numeric value, not a boolean you're giving this. Negative result means sort lower, 0 means leave as it is and positive means sort upper.

In ES6, use something like this:

let top10 = this.topPlayers
    .sort((a,b) => b.stars - a.stars)
    .slice(0,10);

let bottom10 = this.topPlayers
    .sort((a,b) => a.stars - b.stars)
    .slice(0,10);

ΔO 'delta zero'
  • 3,506
  • 1
  • 19
  • 31
1

The Array.prototype.sort expects, as a parameter, a compare function that returns a numeric value instead of a boolean one.

This compare function needs to follow this logic:

function compare(a, b) {
  if (a is less than b by some ordering criterion) {
    return -1; // or any value smaller than zero
  }
  if (a is greater than b by the ordering criterion) {
    return 1; // or any value greater than zero
  }
  // a must be equal to b
  return 0;
}

In your case, if stars is a number, you can sort your array in a descending order in the following way:

this.topPlayers.sort(function(a, b) {
  return b.stars - a.stars;
});

For ascending order, you just need to return a.stars - b.stars instead.

Alberto Trindade Tavares
  • 10,056
  • 5
  • 38
  • 46