1

Using Chrome Version 66.0.3359.117 (Official Build) (64-bit)

Sorting the below array I'm expecting an item with id = 1 to be at the top, which isn't the case. If I reduce the number of items down to 2, sorting works as expected. Can anyone explain why do I get a non deterministic result here?

     let array = [
          { "id": 1, "path": "01.00.00.00.00.00.00" },
          { "id": 2, "path": "01.02.00.00.00.00.00" },
          { "id": 3, "path": "01.02.03.00.00.00.00" },
          { "id": 4, "path": "01.02.04.00.00.00.00" },
          { "id": 5, "path": "01.02.05.00.00.00.00" },
          { "id": 6, "path": "01.02.06.00.00.00.00" },
          { "id": 7, "path": "01.02.05.07.00.00.00" },
          { "id": 8, "path": "01.02.05.07.08.00.00" },
          { "id": 9, "path": "01.02.05.07.08.09.00" },
          { "id": 10, "path": "01.02.04.10.00.00.00" },
          { "id": 11, "path": "01.02.05.07.08.09.11" },
          { "id": 12, "path": "01.02.04.10.12.00.00" }
        ];
        
        array.sort((f, s) => f.path > s.path);
        console.error("Full", array[0].id);
    
        array = [
          { "id": 1, "path": "01.00.00.00.00.00.00" },
          { "id": 2, "path": "01.02.00.00.00.00.00" }
          //{ "id": 3, "path": "01.02.03.00.00.00.00" },
          //{ "id": 4, "path": "01.02.04.00.00.00.00" },
          //{ "id": 5, "path": "01.02.05.00.00.00.00" },
          //{ "id": 6, "path": "01.02.06.00.00.00.00" },
          //{ "id": 7, "path": "01.02.05.07.00.00.00" },
          //{ "id": 8, "path": "01.02.05.07.08.00.00" },
          //{ "id": 9, "path": "01.02.05.07.08.09.00" },
          //{ "id": 10, "path": "01.02.04.10.00.00.00" },
          //{ "id": 11, "path": "01.02.05.07.08.09.11" },
          //{ "id": 12, "path": "01.02.04.10.12.00.00" }
        ];
    
        array.sort((f, s) => f.path > s.path);
        console.error("Reduced", array[0].id);
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Simple.Js
  • 91
  • 6
  • 1
    do you want to sort by id or by path? – Pratik Deoghare May 04 '18 at 13:26
  • You say you sort by id, but you dont – Luca Kiebel May 04 '18 at 13:27
  • If it's worth anything, on Firefox 59 the results are as you are expecting them, i.e. the first item does have `id: 1`. – devius May 04 '18 at 13:28
  • 1
    cheers. @mplungjan thanks for fixing the format. – Simple.Js May 04 '18 at 13:30
  • 1
    Doesn't `sort()` expect you to return a number instead of a boolean? You return true or false, which will be cast to 0 or 1. So you never return -1 or a different negative number, so records will not be sorted correctly if one record belongs before another. – Shilly May 04 '18 at 13:31
  • Possible duplicate of [How to sort strings in JavaScript](https://stackoverflow.com/questions/51165/how-to-sort-strings-in-javascript) – vbriand May 04 '18 at 13:40
  • Please specify if you want to sort by id or by path value. AS I mention before, you need to return a number inside a sort, so if you sort on id, just subtract them. If you want to sort by path though, you need another function to calculate the value, since number order isn't the same as string order. Compare `1000 > 999` and `'1000' > '999'`. So if you need to compare paths, you need to cast the path back to some numerical value. ( I usually use spluit on the dot and multiply the index, so items that start with 01 will be a quadrillion something, etc... ) – Shilly May 04 '18 at 13:40

4 Answers4

2

You have to provide 3 options

array.sort((f, s) => {
  if(f.path < s.path){return -1}
  if(f.path > s.path){return 1} 
  return 0;
});

Basically js comparing function needs to return an integer, since '>' returns a boolean, then true == 1 and false == 0, so when false is returned it is interpreted as the elements are equal, instead of -1 one is maller than the other.

0

First, you are comparing two string as like they are numbers, so I think the compiler transforms the string to numbers and then compare them when you do :

f.path > s.path 
TBenchikhi
  • 11
  • 2
0

You are sorting by path, not id.

Try array.sort((f, s) => f.id - s.id);

fethe
  • 677
  • 6
  • 12
0

You need to change your sort condition to f.id - s.id which is incorrect in your code.

let array = [
  { "id": 1, "path": "01.00.00.00.00.00.00" },
  { "id": 2, "path": "01.02.00.00.00.00.00" },
  { "id": 3, "path": "01.02.03.00.00.00.00" },
  { "id": 4, "path": "01.02.04.00.00.00.00" },
  { "id": 5, "path": "01.02.05.00.00.00.00" },
  { "id": 6, "path": "01.02.06.00.00.00.00" },
  { "id": 7, "path": "01.02.05.07.00.00.00" },
  { "id": 8, "path": "01.02.05.07.08.00.00" },
  { "id": 9, "path": "01.02.05.07.08.09.00" },
  { "id": 10, "path": "01.02.04.10.00.00.00" },
  { "id": 11, "path": "01.02.05.07.08.09.11" },
  { "id": 12, "path": "01.02.04.10.12.00.00" }
];

array.sort((f, s) => f.id - s.id);
console.error("Full", array[0].id);
    
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62