Simple.Js
Simple.Js

Reputation: 91

Javascript Unexpected Sorting Order

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);

Upvotes: 1

Views: 67

Answers (4)

Rihards Fridrihsons
Rihards Fridrihsons

Reputation: 854

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.

Upvotes: 2

Ankit Agarwal
Ankit Agarwal

Reputation: 30739

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);
    

Upvotes: 0

fethe
fethe

Reputation: 697

You are sorting by path, not id.

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

Upvotes: 0

TBenchikhi
TBenchikhi

Reputation: 11

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 

Upvotes: 0

Related Questions