-3

I am sorting my array in JavaScript based on names after then I am sorting it based in joinDate but somehow it is not checking for joiningDate.

Unfortunately, I can't use an if-else condition - I only want to use ternary operators.

My code is like this:

person.sort(((a, b) => (a.name > b.name)  ? 1 : (a.joinDate > b.joinDate) ? 1 : -1));

It is sorting the names but not sorting the joinDate property

My list look like this:

{
"data": [
     {
         "id": "fdsf",
         "name": "Julie",
         "joinDate": "01/10/2019"

      },
    ]
}
5
  • 1
    You aren't covering all 4 cases :) And why didn't you post it to your previous question here? Commented Sep 2, 2020 at 20:09
  • It's not clear why you think an array of length 1 is sufficient to test a sorting function(!) But your code contains a logical error, as presumably you always want to return -1 if a.name < b.name, rather than fall back to comparing the joinDate properties. This will rapidly get very messy to do with nested ternaries - as a general rule I would say NEVER nest more than 2 ternaries, and be very wary of even nesting 2 of them. Commented Sep 2, 2020 at 20:11
  • your sort by joinDate will put "02/03/2018" AFTER "01/10/2019" which is a bit strange Commented Sep 2, 2020 at 20:23
  • Duplicate of How to sort an array of objects by multiple fields?. Commented Sep 3, 2020 at 15:19
  • Consider using ISO dates for joinDate, i.e. 2019-10-01 (yyyy-MM-dd) instead of 01/10/2019. One of the main advantages is that they sort naturally alphanumerically. Commented Sep 3, 2020 at 15:22

2 Answers 2

10

Your comparison function does not cover all the possible cases properly.

Instead, you may use String.prototype.localeCompare() to sort by either name or joinDate (when names are same) like that:

person.sort((a,b) => 
   a.name.localeCompare(b.name) || a.joinDate.localeCompare(b.joinDate))

I guess, that approach would be much easier to scale to arbitrary number of sorting parameters.

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

Comments

6

The test should be (assuming your date format is dd/mm/yyyy)

if (a.name > b.name) return 1;
if (a.name < b.name) return -1;
let [a_dd, a_mm, a_yy] = a.joindate.split("/");
let [b_dd, b_mm, b_yy] = b.joindate.split("/");
if (a_yy !== b_yy) return a_yy - b_yy;
if (a_mm !== b_mm) return a_mm - b_mm;
if (a_dd !== b_dd) return a_dd - b_dd;
return 0;

4 Comments

Or in insane ternary: a.name > b.name ? 1 : a.name < b.name ? -1 : a.joindate > b.joindate ? 1 : a.joindate < b.joindate ? -1 : 0
regarding that ternary... please don't do that to the next person who has to decipher your code :)
@Sheraff Perfect. it's for personal use so I little messy code is okay as long as it work :-p Thanks!
@NehaSharma I wrote this as a joke... -_-

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.