Why does this sort method not work?

It looks logically sound, and I know this can be done with objects, but why doesn’t it work with elements inside arrays? I was expecting the method to sort the arrays based on the second value of each nested array in x

let x = [
    [1, 'B'],
    [2, 'A']
    ]
x.sort((a, b) => a[1] - b[1])
console.log(x)

'A' - 'B' // NaN
you’re trying to subtract strings

this sorting method x.sort((a, b) => a[1] - b[1]) is used for sorting numbers and not strings.

in order to do this sorting you can first reverse the nested array and then can use x.sort(). After that again reverse the nested array, you will get your result.

What happens when your run the sort method is the element in the array is converted into strings and its utf-16 units are compared. considering each element in your array is another array, when that’s converted into a string the utf-16 code units does not exist so nothing happens, how ever you can sort those elements in the nested array by simply looping through the main array and applying a sort on the index .
Here’s a useful link
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

I think if the array needs to be sorted by the second element, reverse won’t help you much as well as sorting by the first element because we don’t know if the number corresponds to the string in nested array in terms of order.

The documentation talks about default sorting, but the author uses his own function

The other issue is that we would have to sort based on the reference. Actually, it would be running the toString method on each of those and using those to sort. So, you could do the reverse, then reverse back:

const arr = [
  [1, 'cherry'],
  [2, 'apple'],
  [3, 'date'],
  [4, 'elderberry'],
  [5, 'banana'],
]

const sorted = arr.map(a => a.reverse()).sort().map(a => a.reverse())

sorted.forEach(e => console.log(e))
// [2, 'apple']
// [5, 'banana']
// [1, 'cherry']
// [3, 'date']
// [4, 'elderberry']

No, that is an un UGLY solution. And that would be prone to bugs if people change the data structure and there are probably some ugly edge cases. No one will hire you if that is how you do it. No, you need a custom sorting function, but as mentioned, you need to sort those strings properly. If this were an array of strings, the default sort function would work fine. But it isn’t, so it won’t.

The documentation (always read the docs) says that if the callback returns a number greater than 0, then a should come before b, less that 0 and b should come before a, and 0 means they are the same.

So, if you want to sort this, you need something like this:

const sortElements = (a, b) => {
  if (a[1] > b[1]) return 1
  if (a[1] < b[1]) return -1
  return 0
}

const sorted = arr.sort(sortElements)

Or a common way to do something like this would be:

const sortElements = ([_dropA, a], [_dropB, b]) => a > b ? 1 : a < b ? -1 : 0

There are ways to make it more flexible and maintainable, but given the data we were, that will work.

1 Like

Thank you, I used this custom sorting function in the challenge

Sorry, if I’d realized this was a challenge, I would n9t have just gven you the answer. Make sure you understand it.