-1

I have an array which should be sorted according to most highest value to be first but sorting is not working as expected.

  positionsArray = [
    "50000_q3C3lMizwTYCJmkrfdhFiVpM2Jl2",
    "900_dvceb96flknaevo1yibukaowmi12",
    "2000_hAoH1bbfc4beHn4GSQc7CAmUQI83",
    "1000_wLK0w821hQRi8uWrAInWiPuQ9R22"
],

when I do

let sortedArray = positionsArray.sort();
let reverseSortedArray = positionsArray.sort().reverse();

I am getting below

console.log(sortedArray);
 [
    "900_dvceb96flknaevo1yibukaowmi12",
    "50000_q3C3lMizwTYCJmkrfdhFiVpM2Jl2",
    "2000_hAoH1bbfc4beHn4GSQc7CAmUQI83",
    "1000_wLK0w821hQRi8uWrAInWiPuQ9R22"
],

and

console.log(reverseSortedArray)
"reverseSortedArray": [
        "900_dvceb96flknaevo1yibukaowmi12",
        "50000_q3C3lMizwTYCJmkrfdhFiVpM2Jl2",
        "2000_hAoH1bbfc4beHn4GSQc7CAmUQI83",
        "1000_wLK0w821hQRi8uWrAInWiPuQ9R22"
    ],

But my Expected answer is

 [
    "50000_q3C3lMizwTYCJmkrfdhFiVpM2Jl2",
    "2000_hAoH1bbfc4beHn4GSQc7CAmUQI83",
    "1000_wLK0w821hQRi8uWrAInWiPuQ9R22"
    "900_dvceb96flknaevo1yibukaowmi12",
],
cakePHP
  • 425
  • 1
  • 4
  • 23
  • 1
    Sort mutates original array which maybe giving you wrong result. Do let sortedArray = positionsArray.slice()sort(); to ensure you aren't mutating positionsArray for your next command. – Steve Tomlin Aug 02 '21 at 09:39
  • I think you copy/pasted the "sortedArray" wrongly: In chrome it returns 1000, 2000, 50000 and 900. The reason: 1 is before 2 and 2 before 5 and 5 before 9. You are sorting text (strings)... – NoRyb Aug 02 '21 at 09:41
  • Also its sorring by string, not number. Hence why order is 9, 5, 2, 1 – Steve Tomlin Aug 02 '21 at 09:43

4 Answers4

1

As per MDN documentation:

The default sort order is ascending, built upon converting the elements into strings, then comparing their sequences of UTF-16 code units values.

So, if you do not provide a sorting function, Array.prototype.sort() will arrange the items based on a string comparison. In order to obtain what you want, you would need to do something like:

// input data
const positionsArray = [
  "50000_q3C3lMizwTYCJmkrfdhFiVpM2Jl2",
  "900_dvceb96flknaevo1yibukaowmi12",
  "2000_hAoH1bbfc4beHn4GSQc7CAmUQI83",
  "1000_wLK0w821hQRi8uWrAInWiPuQ9R22"
]

// sorting
const output = positionsArray.sort((a, b) => {
  // extract the "numeric" part of your string (`split('_')[0]`)
  // and convert it to a number (`parseInt()`)
  const aNum = parseInt(a.split('_')[0]);
  const bNum = parseInt(b.split('_')[0]);
  
  // use the numeric values obtained to sort the items in the array
  return bNum - aNum; // or aNum - bNum, if you want them in ascending order
});

// test
console.log(output);
secan
  • 2,622
  • 1
  • 7
  • 24
0

I Found the solution over here

https://stackoverflow.com/a/38641281/12917651

var collator = new Intl.Collator(undefined, {numeric: true, sensitivity: 'base'});
var myArray = ['1_Document', '11_Document', '2_Document'];
console.log(myArray.sort(collator.compare).reverse());
cakePHP
  • 425
  • 1
  • 4
  • 23
  • That's good; it would have been even better researching the (already available) solution *before* posting the question. ;) – secan Aug 02 '21 at 10:08
-1

I think the info you are looking for is here. When you don't supply a sort function, it sorts based on the first character in the string ('5' is not 5, it is treated as it's character code 53). If the first character is the same on multiple elements it bases the sort on the second character, so and and so forth.

Priswall
  • 21
  • 5
  • const months = ['12_March', '32_Jan', '5_Feb', '2_Dec']; months.sort(); console.log(months); try this does this returning sorted value ? – cakePHP Aug 02 '21 at 09:46
  • 2
    @cakePHP yes, it does. It's lexicographically sorted. That's the default sorting criteria. If you want a different one, you need to supply the comparison function. – VLAZ Aug 02 '21 at 09:47
  • after sorting 5_Feb should be first but it remains last – cakePHP Aug 02 '21 at 09:52
  • I think I understand your confusion. I updated my answer to hopefully help – Priswall Aug 02 '21 at 09:55
  • @cakePHP `5` sorts after `1` and after `2` and after `3`. Therefore, it's the last one. If you have `"apple"` and `"banana"` would you expect `"banana"` to be sorted first? No, because `b` sorts after `a` – VLAZ Aug 02 '21 at 09:58
-1

The array is compared as string.

If you need to extract the number part to compare, create your own .sort(compare) function

Reference:

compareFunction


const array = [
  "50000_q3C3lMizwTYCJmkrfdhFiVpM2Jl2",
  "900_dvceb96flknaevo1yibukaowmi12",
  "2000_hAoH1bbfc4beHn4GSQc7CAmUQI83",
  "1000_wLK0w821hQRi8uWrAInWiPuQ9R22"
];

function sortString(array) {
  return array.sort((a, b) => {
    return n(a) - n(b);
  });
}

function n(s) {
  return s.match(/^(\d+)/)[1];
}

console.log(sortString(array));
idfurw
  • 5,727
  • 2
  • 5
  • 18