1

Using javascript sort() method, I am trying to do sorting a list but sorting have in a group of even numbers and odd numbers.

The code which I tried is working fine with small list but if the list becomes big its not getting me proper result. Here is my code.

var n = [10,20,21,4,5,6,7,99,0,12,13];
//var n = [10,20,0,12];
n.sort(function(a,b){
 if (a % 2 !=b % 2 ){
   return a%2;
  }else {
    return a - b; 
  }
});

The above code gives me as per accepted result like this Ans - [0, 4, 6, 10, 12, 20, 5, 7, 13, 21, 99] and the second Ans is:- [0, 10, 12, 20]

Working fine with this lists but if I changed into this

var n = [10,20,21,4,5,6,7,99,0,12,13,10,20,21,4,5,6,7,99,0,12,13,10,20,21,4,5,6,7,99,0,12,13,10,20,21,4,5,6,7,99,0,12,13];

But in this case the result is something like this which is not proper.

Giving me Ans like this

[0, 0, 0, 0, 4, 4, 4, 4, 6, 6, 6, 6, 10, 10, 10, 10, 12, 5, 12, 5, 12, 5, 20, 20, 20, 20, 5, 12, 7, 7, 7, 7, 13, 13, 13, 13, 21, 21, 21, 21, 99, 99, 99, 99] its a mixing of odd and even numbers.

Its giving me not proper result. Any suggestion.

VisioN
  • 143,310
  • 32
  • 282
  • 281
Soarabh
  • 2,910
  • 9
  • 39
  • 57

3 Answers3

15

The short of the shortest:

n.sort(function(a, b) {
    return a % 2 - b % 2 || a - b;
});

To make it work with negative numbers we can add Math.abs():

n.sort(function(a, b) {
    return Math.abs(a % 2) - Math.abs(b % 2) || a - b;
});

Or even more compact variant using bitwise AND:

n.sort(function(a, b) {
    return (a & 1) - (b & 1) || a - b;
});

The most compact version (ES6):

n.sort((a, b) => (a & 1) - (b & 1) || a - b);
VisioN
  • 143,310
  • 32
  • 282
  • 281
  • 1
    that short version is beautiful :) – Alnitak Oct 30 '12 at 13:26
  • 1
    Good job! I started writing an answer, but gave up as soon as I saw this. Elegant and correct. – Jordan Gray Oct 30 '12 at 13:37
  • 1
    @VisioN: It does not work with negative numbers correctly (see my answer). Also, if a and b are equal, the results are undefined by the ECMAScript spec per MDN: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/sort – Xitalogy Oct 30 '12 at 14:06
  • @aeoril Problem with negative numbers can be easily fixed. Regarding equality, see MDN: *If `compareFunction(a, b)` returns `0`, leave `a` and `b` unchanged with respect to each other, but sorted with respect to all different elements.* – VisioN Oct 30 '12 at 14:13
  • @VisioN Notice note on MDN: "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 does not guarantee this behaviour, and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this" – Xitalogy Oct 30 '12 at 14:22
  • @VisionN: to fix spec problem: function sort1 (a, b) { if (a === b) { return 1; } return Math.abs(a % 2) - Math.abs(b % 2) || a - b; }; – Xitalogy Oct 30 '12 at 14:34
  • @VisionN: To fix the spec problem better: console.log(n.sort(function (a, b) {return (a & 1) - (b & 1) || a - b || 1;}));​ – Xitalogy Oct 30 '12 at 15:49
1

Change the code as follows:

n.sort(function(a,b){
 if (a % 2 != b % 2 ){
   return a%2;
  }else {
      return (a - b) > 0 ? 1 : -1; 
  }
});

Working sample is here.

Edit:

n.sort(function(a,b){
 if (a % 2 != b % 2 ){
     return a%2 == 0 ? -1 : 1; // this is the fix :)
  }else {
      return (a - b) > 0 ? 1 : -1; 
  }
});

Edit 2: I've modifed the code for negative numbers. See working sample.

n.sort(function(a,b){
 if (a % 2 != b % 2 ){
   return Math.abs(a)%2;
  }else {
      return a > b ? 1 : -1; 
  }
});
Zafer
  • 2,180
  • 16
  • 28
0

My try:

fiddle

var n = [10,20,21,4,5,6,7,99,0,-12,12,13,-45,10,20,21,-13,4,5,6,7,99,0,12,13,10,-99,20,21,4,5,6,7,99,0,12,13,10,20,21,4,5,6,7,99,-15,-18,0,12,13];

function sort(a, b) {
    if (!(a % 2) && !(b % 2)) {
        return a > b ? 1 : -1;
    }
    if ((a % 2) && (b % 2)) {
        return a > b ? 1 : -1;
    }
    if ((a % 2) && !(b % 2)) {
        return 1;
    }
    return -1;
}
console.log(n.sort(sort));​
Xitalogy
  • 1,592
  • 1
  • 14
  • 17