2

say I have an array that I want to sort, that a certain element will be first, and leave the rest the way it is.

for example [1,2,3,4] and I want the 2 to be at the beginning of the array

[1,2,3,4].sort((a,b)=> a == 2 ? -1 : 0)

in chrome the output is as expected

// chrome
[2,1,3,4]

but in Firefox the output is different and the 2 is not first

// firefox
[1,2,3,4]
2
  • 1
    You're supposed to compare two elements, not return whether the first of the two equals 2. Commented Apr 20, 2021 at 13:41
  • 1
    That is no proper ordering. Depending on the implementation of the sort different outcomes can and will happen. Commented Apr 20, 2021 at 13:42

2 Answers 2

7

You also need to handle the cases were b is 2 properly:

 .sort((a, b) => (b === 2) - (a === 2))

but in Firefox the array is not sorted

Not quite, Firefox might use a different sorting algorithm, such that the sorter is called with different arguments in a different order. The array is only sorted correctly in all different implementations if the following conditions are always true:

  sorter(a, a) === 0
  sorter(a, b) === - sorter(b, a)

Note that sorting is usually O(n log n) average case (though it could be better if a lot of elements are equal), whereas the problem can be solved in O(n):

 const withoutTwo = array.filter(it => it !== 2);
 const result =
   Array.from({ length: array.length - withoutTwo.length }).fill(2)
    .concat(withoutTwo);
Sign up to request clarification or add additional context in comments.

6 Comments

This works because false - false === 0 and according to developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… "If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other, but sorted with respect to all different elements. Note: the ECMAScript standard only started guaranteeing this behavior in 2019, thus, older browsers may not respect this.", right?
@luk2302 exactly. In other words although { 2 } < N \ { 2 } only defines a partial order, for two equal elements the index is taken, so we're basically sorting N², (el, index) > (el2, index2) and that should be a total order if I'm not mistaken
Your answer was right though in the way that one could skip a lot of unneccessary comparisons with a different approach, reducing complexity to O(n)
Yeah, but I was not aware of the specification and was honestly not expecting your code / any sort to work until I actually tried your snippet out with different inputs.
sorter(a, b) === - sorter(b, a) should probably be sign(sorter(a, b)) === - sign(sorter(b, a)) ;)
|
1
[1,2,3,4].sort((a,b)=> a == 2 ? -1 :  (b==2 ? 1 :0))

1 Comment

A small explanation about what the code does or where the OP's error was would be a great addition to otherwise code only, thus a low quality post

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.