I am trying to separate the negative & positive elements of an array in Javascript, such that afterwards first come all negative elements and then the positive elements, each in the original order.
Example:
Input array: [1,2,-3,-2,4]
Output array: [-3,-2,1,2,4]
Input array: [3,2,-1,0,-4,3,6,-7,-6]
Output array: [-1,-4,-7,-6,3,2,0,3,6]
I can do it using a temporary array with use of push() method, but how to do this without using a temporary array in that array only?
Use sort()
var res = [1, 2, -3, -2, 4].sort(function(a, b) { return a - b; }); // or just use, var res = [1, 2, -3, -2, 4].sort(); document.write(JSON.stringify(res));
For getting sorted as you like you need to add custom sorting conditions.
Update : In your case sort()
will not preserve position of same valued items, so instead you can use filter()
and concat()
. Using filter()
get negative , zero and positive numbers in different array after that concatenate it whatever order you want using concat()
.
var res = [3, 4, -6, 0, -8, -1, 3, -6, 1, -8, -6, -1]; //get positive negative values var neg = res.filter(function(v) { return v < 0; }), // get positive values pos = res.filter(function(v) { return v > 0; }), // get zeros zero = res.filter(function(v) { return v == 0; }); // concat result arrays res = neg.concat(zero, pos); document.write(JSON.stringify(res));
Same method , without using any additional variable
var res = [3, 4, -6, 0, -8, -1, 3, -6, 1, -8, -6, -1]; res = res.filter(function(v) { return v < 0; }).concat(res.filter(function(v) { return v == 0; }), res.filter(function(v) { return v > 0; })); document.write(JSON.stringify(res));
When sorting by a numeric value, the basic form of the function to pass to sort
is
function comparator(a, b) { return func(a) - func(b); }
Here func
is a function which takes the element to be sorted, and returns the sort index to use.
To sort by "sign" (negative vs. positive), use Math.sign
, which gives the sign of the element:
function sign_comparator(a, b) { return Math.sign(a) - Math.sign(b); } array.sort(sign_comparator)
This will sort negative numbers first and positive numbers last, otherwise leaving their order unchanged (but see important note below for some browsers which may not leave the order unchanged).
a = [3,2,-1,0,-4,3,6,-7,-6] a.sort(sign_comparator) < [-1, -4, -7, -6, 0, 3, 2, 3, 6]
Math.sign
is ES6. For platforms such as IE which do not support it, write it yourself:
function sign(x) { return x < 0 ? -1 : x > 0 ? +1 : 0; }
If you want to write your code a bit more semantically, define a generic function to create a comparator function as
function make_numeric_comparator(func) { return function(a, b) { return func(a) - func(b); }; }
Now you can write your sort as
a.sort(make_numeric_comparator(Math.sign))
Important note on stability
In some cases, as the OP helpfully pointed out, the original order is not always preserved. This behavior is known as the stability of the sort. In simple terms, does the sort preserve the original order of pairs of items for which the sort function returns 0? It turns out that Chrome's sort is not stable, at least in some cases, which is what you are seeing. On the other hand, FF sort is stable. For details, see this SO question and this V8 issue https://code.google.com/p/v8/issues/detail?id=90. Of course, we want our sort to be stable in all browsers. So does that mean this approach will not work?
No, but it means we have to do a workaround. Here is a stable sort function:
function stable_sort(array, sortfunc) { function _sortfunc(a, b) { return sortfunc(array[a], array[b]) || a - b; } return array.map((e, i) => i) . sort(_sortfunc) . map(i => array[i]); } > stable_sort([3, 4, -6, 0, -8, -1, 3, -6, 1, -8, -6, -1], sign_comparator) < [-6, -8, -1, -6, -8, -6, -1, 0, 3, 4, 3, 1]
What this is doing is creating a parallel array of indexes, from 1 to array.length-1
, with array.map((e, i) => i)
. It sorts those indexes with a special sort function which calls the original sort function, but if that function returns 0 (sort in same place), it imposes the ordering of the indexes. After the array of indexes is sorted, it then uses that to look up into the original array to create the result (with the map(i => array[i])
).
This may be too much work, so you may prefer another solution. On the other hand, you may want stable sorting in other contexts as well, and so if you have the stable_sort
function defined, this approach would still be more straightforward than filtering out the numbers with each sign and recombining them.
for the precise requirement of seperating positive and negative number
var t = [-1,-2,-3,5,6,1] var positiveArr = []; var negativeArr = []; t.forEach(function(item){ if(item<0){ negativeArr.push(item); } else{ positiveArr.push(item) }) console.log(positiveArr) // output [5, 6, 1] console.log(negativeArr) // output [-1, -2, -3]