0

I have an array, productData with multiple properties. This is how I currently sort the array by monthlyCost, ascending.
How can I modify this to sort all items by a boolean property isPromoted, followed by monthlyCost?
My array should start with all items where isPromoted == true sorted by monthlyCost, then all items where isPromoted == false sorted by monthlyCost.

    productData.sort((a, b) => {
      if (a.monthlyCost > b.monthlyCost) {
        return 1;
      } else if (a.monthlyCost < b.monthlyCost) {
        return -1;
      } else {
        return 0;
      }
    });
noclist
  • 1,659
  • 2
  • 25
  • 66
  • 1
    if `isPromoted` is not equal - then return either `1` or `-1` - if it is equal, then return the result of your existing comparison – Daniel A. White Jun 16 '22 at 14:37
  • 1
    -Equal to what? – noclist Jun 16 '22 at 14:41
  • Does this answer your question? [How to sort an array of objects by multiple fields?](https://stackoverflow.com/questions/6913512/how-to-sort-an-array-of-objects-by-multiple-fields) – pilchard Jun 16 '22 at 14:51
  • and [Javascript sort array of objects by a boolean property](https://stackoverflow.com/questions/17387435/javascript-sort-array-of-objects-by-a-boolean-property) – pilchard Jun 16 '22 at 14:52

1 Answers1

3

You can use this callback:

productData.sort((a, b) => +b.isPromoted - +a.isPromoted || a.monthlyCost - b.monthlyCost);

The unary plus is optional in plain JavaScript, but in a TypeScript context, you'll need to be explicit about the conversion to number and apply +.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • So why is b minus a for `isPromoted` but a minus b for `monthlyCost`? – noclist Jun 16 '22 at 14:48
  • Because you want true to come before false, while in numerical order, false (0) would come before (1). So by reversing the expression the order will be as you wish it to be. – trincot Jun 16 '22 at 14:54
  • Thank you so much! I'm now trying to throw in another property to sort, `promotionLevel` which is either 1 or 2. Adding this in to your expression, `productData.sort((a, b) => +b.isPromoted - +a.isPromoted || a.promotionLevel - b.promotionLevel || a.monthlyCost - b.monthlyCost);` doesn't seem to be working as I expect. Can you tell what I'm doing wrong? (I want promotionLevel 1 to come before 2) – noclist Jun 16 '22 at 14:58