3

I am trying to sort an array so that all the zeros are at the end. However, I don't want the list to be numerically sorted, all the numbers above zero should stay in the same order. Here's what I've got so far:

function placeZerosAtEnd(arr) {
    return arr.sort(compareForSort);
}
function compareForSort(first, second) {
    return first == 0 ? 1 : 0;
}
placeZerosAtEnd([9,0,9,1,0,2,0,1,1,0,3,0,1,9,9,0,0,0,0,0]);

This should return [9,9,1,2,1,1,3,1,9,9,0,0,0,0,0,0,0,0,0,0], but actually returns [3,9,9,1,9,2,9,1,1,1,0,0,0,0,0,0,0,0,0,0]. The zeros are correct, but the other numbers are in a strange order. What is going on here?

http://jsfiddle.net/v67fx4zk/

Stormdamage
  • 389
  • 1
  • 5
  • 16

7 Answers7

11

As other have said, using .sort() was wrong in this instance. This is the code I used in the end, as suggested by elclanrs in the comments below my initial post.

function placeZerosAtEnd(arr) {
    return arr.filter(isntZero).concat(arr.filter(isZero));
}
function isntZero(element) {
    return element > 0;
}
function isZero(element) {
    return element == 0;
}
Stormdamage
  • 389
  • 1
  • 5
  • 16
2

I don't think you can accomplish this with the sort function. Depending on the sort method the browser uses (quicksort, merge sort, etc.), the sort function works by swapping items into place. So there's no telling where the non-zeroes will end up ... your algorithm simply ensures that they'll appear before the 0s.

Here's a function that will accomplish what you're trying:

function placeZerosAtEnd(arr) {
  for(var i = 0 ; i < arr.length ; i++) {
    if(arr[i]===0) arr.splice(arr.length-1, 0, arr.splice(i, 1)[0]);
  }
  return arr;
}
Rick Hitchcock
  • 35,202
  • 5
  • 48
  • 79
2

you can use this some way too

let listSort = [9, 0, 9, 1, 0, 2, 0, 1, 1, 0, 3, 0, 1, 9, 9, 0, 0, 0, 0, 0],
    isntZero = [],
    isZero = []

for (let i = 0; i < listSort.length; i++) {
  if (listSort[i] == 0)
    isZero.push(listSort[i])
  else
    isntZero.push(listSort[i])
}

let output = isntZero.concat(isZero)

console.log(JSON.stringify(output))
adiga
  • 34,372
  • 9
  • 61
  • 83
2

The trivial solution with sort: "bubble down" zeros against non-zeros:

[9,0,9,1,0,2,0,1,1,0,3,0,1,9,9,0,0,0,0,0].sort((a, b) => {
  if (a !== 0 && b === 0) return -1;
  if (a === 0 && b !== 0) return 1;
  return 0;
})

// [9, 9, 1, 2, 1, 1, 3, 1, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
gazdagergo
  • 6,187
  • 1
  • 31
  • 45
0

In your example the sort function is doing exactly what it's meant to.

You're expecting a stable sort, but a stable sort is not guaranteed by the javascript sort algorithm.

See this question for a discussion on stable sorting in javascript.

Community
  • 1
  • 1
Andrew Shepherd
  • 44,254
  • 30
  • 139
  • 205
0

You can use arr.sort to solve this problem

reference: Array.sort

   function placeZerosAtEnd(arr) {

     arr.sort(function(key1,key2) {

      if (key1 == 0 ) return 1;
      return -1;
    });    
    return arr;
  }
Vijay Palaskar
  • 526
  • 5
  • 15
0
arr.sort((a,b) => a - b).reverse()