2

I'm facing with a sorting problem in javascript. I wrote a simple sorting function where I want the null elements on top:

This is the function:

var mySort = function(a, b) {
 if (!a && !b) return 0;
 if (!a) return -1;
 if (!b) return -1;
 if (a > b) return 1;
 if (a < b) return -1;
 return 0;
}

Let's take the following array as example:

var array = [1, 9, 4, 8, null, 2, 3, 4, null, 6, 3, 2, 8, 9, 5];

By calling array.sort(mySort) the non null values are always sorted, but the null values position alternate from the beginning and the end of the array:

Odd calls: [null, null, 1, 2, 2, 3, 3, 4, 4, 5, 6, 8, 8, 9, 9]
Even calls: [1, 2, 2, 3, 3, 4, 4, 5, 6, 8, 8, 9, 9, null, null]

Why?

Edit:
In a comment HMR head me to an error in the algorithm: if (!b) return -1; should be if (!b) return 1;. Now it works fine with stings and numbers.

6
  • 2
    You can call it as many times as you want if you do: array.slice().sort(mySort) if one item is falsy (null) it's either put on the start or the end but if they're both null then none of the items are moved. So the nulls will group at the start or the end. If you do if (!b) return 1; then it'll also always be the same. Commented Nov 21, 2018 at 16:02
  • I don't really get the point of your answer. I already know about slicing the array, but IMHO it is a hack. I'd like to know why the null are switched even if the function is the same...it should be always the same result... Commented Nov 22, 2018 at 7:00
  • No it doesn't. sort mutates and you return -1 for cases where a is null and b is not or vice versa, this causes null's to either be at the start or at the end depending on the order sort will compare the items and where the items were to start with. You could either not mutate the array (use slice) or return a different value when one is null. Commented Nov 22, 2018 at 8:03
  • 2
    Damn.... if (!b) return -1; is wrong, it should be if (!b) return 1; Now it works fine!.Thanks! Commented Nov 22, 2018 at 8:05
  • do you have null or 'null' as string in the array? Commented Nov 22, 2018 at 10:16

1 Answer 1

1

You need to use the relation between two items. If both items are null, then change nothing, if you have one null value, then it depends on the position.

The best way is to check the items and get the delta of the check for sorting.

function mySort(a, b) {
    return (b === null) - (a === null) || a - b;
}

var array = [1, 9, 4, 8, null, 2, 3, 4, null, 6, 3, 2, 8, 9, 5];

array.sort(mySort);
console.log(array);

array.sort(mySort);
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

6 Comments

I copied your example, it behavies as mine does. Try to call the sort a second time, the null values will go at the end.
it keeps the order. on which user agent is this running?
Chrome Version 70.0.3538.102
it is working fine with 70.0.3538.102 and the very actual version 70.0.3538.110 on windows.
Ok, but I need something that works on (almost) every browser.
|

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.