Different output between codcademy and VScode with same code

Hello,

const years = [1970, 1999, 1951, 1982, 1963, 2011, 2018, 1922]
const sortYears = arr => {
       return arr.sort((year1, year2) => year1 < year2 ? 1: 0);
}

console.log(sortYears(years))

when I run this code on Codcademy prompt, I have the expected output:

But if I run it in VScode, it looks like no sort is applied to my original array, my output is :

Anyone has an idea of the reason for this strange thing?

1 Like

Hi
I’m on this for like 40 minutes and here’s my 2 cents but take it with a grain of salt.

The comparison function works with the return result with the following reasoning:

You compare function returns 1 if a is lower than b which means a will be sorted after b, a is being ‘pushed’ to the right if you will, else it returns 0 which means nothing will change.

Now the thing is the order of comparison depends on the sorting algorithm used by the JavaScript engine, which is not specified by the language standard. So consider the following example, in a certain implementation of the sort function the higher values happen to be a so the function returns 0, consequently nothing changes like in VSCode. But in another implementation where higher values were to be b than the a value would be pushed to right and it would be sorted in descending order like in the workspace.

The problem in your thinking is that you assume the comparison will be done from left to right which may not be the case.

However if you were to change the 0 value to -1 the order would not matter. If the higher value was a it would be pushed to left instead of staying as they are. It’s almost always better the explicitly use all 3 return values (negative,0,positive) for clarity.

This is the best explanation I could come up with but I’m not sure

3 Likes

I looked at the thread earlier and couldn’t quite understand the cause. bariskaraer1’s explanation encouraged me to experiment a bit more and dive into the documentation again.

Documentation: Array.prototype.sort() - JavaScript | MDN

Here are a few relevant remarks from the documentation,

1 Like

I’m at a loss as to how the Code Academy works at all. Depending on the engine, you could have just gotten lucky.

It’s not VS Code so much as the engine VS Code is using. My engine, node v18.13.0, also doesn’t sort with what you have. Let’s see why.

So:

const sortYears = (arr, fCmp) =>
    arr.sort(fCmp);

const test = fCmp => {
    const arr = [1970, 1999, 1951, 1982, 1963, 2011, 2018, 1922];
    console.log(fCmp.name);
    console.log(JSON.stringify(arr));
    console.log(JSON.stringify(sortYears(arr, fCmp)));
};

const cmp1 = (year1, year2) => year1 < year2 ? 1: 0;

test(cmp1);

Results:

cmp1
[1970,1999,1951,1982,1963,2011,2018,1922]
[1970,1999,1951,1982,1963,2011,2018,1922]

Perfect. Now, let’s watch:

const cmp2 = (year1, year2) => {
    const result = year1 < year2 ? 1: 0;
    console.log({ result, year1, year2});
    return result;
};

Results:

cmp2
[1970,1999,1951,1982,1963,2011,2018,1922]
{ result: 0, year1: 1999, year2: 1970 }
{ result: 1, year1: 1951, year2: 1999 }
{ result: 0, year1: 1982, year2: 1951 }
{ result: 1, year1: 1963, year2: 1982 }
{ result: 0, year1: 2011, year2: 1963 }
{ result: 0, year1: 2018, year2: 2011 }
{ result: 1, year1: 1922, year2: 2018 }
[1970,1999,1951,1982,1963,2011,2018,1922]

Well, that was less than exciting. Let’s step back. You know that 0 means they match? If each time I get a 1 I needn’t swap, then no sorting is done.

Right, let’s fix it:

const cmp3 = (year1, year2) => {
    const result = year1 - year2;
    console.log({ result, year1, year2});
    return result;
};

Results:

cmp3
[1970,1999,1951,1982,1963,2011,2018,1922]
{ result: 29, year1: 1999, year2: 1970 }
{ result: -48, year1: 1951, year2: 1999 }
{ result: -48, year1: 1951, year2: 1999 }
{ result: -19, year1: 1951, year2: 1970 }
{ result: 12, year1: 1982, year2: 1970 }
{ result: -17, year1: 1982, year2: 1999 }
{ result: -19, year1: 1963, year2: 1982 }
{ result: -7, year1: 1963, year2: 1970 }
{ result: 12, year1: 1963, year2: 1951 }
{ result: 41, year1: 2011, year2: 1970 }
{ result: 12, year1: 2011, year2: 1999 }
{ result: 36, year1: 2018, year2: 1982 }
{ result: 7, year1: 2018, year2: 2011 }
{ result: -60, year1: 1922, year2: 1982 }
{ result: -41, year1: 1922, year2: 1963 }
{ result: -29, year1: 1922, year2: 1951 }
[1922,1951,1963,1970,1982,1999,2011,2018]

Neat, a lot more hits on that one. Hmm, going the wrong way. The reverse is simple:

// we'll just return the value for this one
const cmp4 = (year1, year2) => year2 - year1;

Results:

cmp4
[1970,1999,1951,1982,1963,2011,2018,1922]
[2018,2011,1999,1982,1970,1963,1951,1922]

Now, if you must use that ternary you can write it like so:

const cmp5 = (year1, year2) => year1 < year2 ? 1 : -1;

Which, of course, is the answer. Thanks for reading. Hope something sparked some ideas.

1 Like

@bariskaraer1 @mtrtmk @baavgai thank you for your explanations and your time.

I have read the documentation in more detail, and with your explanations, it’s much clearer now.
Great demo Baavgai, I have a better understanding with the intellectual path you have developed.

To move towards a better-formed comparator, I finally arrived at this code:

const years = [1970, 1999, 1951, 1982, 1963, 2011, 2018, 1922];
const sortYears = arr => {
       return arr.sort((a, b) => a-b> 0 ? 1 : a-b< 0 ? -1 : 0);
};
1 Like