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?
/
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/
Share Improve this question asked Sep 23, 2014 at 23:04 StormdamageStormdamage 3891 gold badge5 silver badges18 bronze badges 3 |7 Answers
Reset to default 11As 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;
}
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]
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;
}
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))
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.
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;
}
arr.sort((a,b) => a - b).reverse()
xs.filter(isntZero).concat(xs.filter(isZero))
– elclanrs Commented Sep 23, 2014 at 23:18second
is0
? – Sebastien C. Commented Sep 24, 2014 at 10:49