4

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?

Philipp Wendler
  • 11,184
  • 7
  • 52
  • 87
aryan
  • 163
  • 1
  • 1
  • 11
  • https://www.google.com/search?q=sort+array+javascript –  Oct 10 '15 at 07:33
  • @torazaburo , could you sort [3, 4, -6, 0, -8, -1, 3, -6, 1, -8, -6, -1] this to [-6,-8,-1,-6,-8,-6,-1,3,4,0,3,1] this array.I don't want minimum and maximum value element .I just want to separate positive and negative element without changing their relative position. I getting difficulty while sorting this array.for more reference just check the conversation between me and pranav on answer. – aryan Oct 10 '15 at 08:09
  • @aryan I think the term "sort" is misleading here, better not use it for this purpose (people will assume you want a fully sorted array). I edited your question to make your intent clear by phrasing it differently. – Philipp Wendler Oct 10 '15 at 08:57
  • Thanks @Philipp Wendler. Now i don't want to explain question any more! :) – aryan Oct 10 '15 at 09:05
  • https://jsfiddle.net/gmxa8pju/1/ – Pranav C Balan Oct 10 '15 at 09:52
  • Dear @aryan, did any of the answers help you out? –  Oct 11 '15 at 16:26
  • @torazaburo , can you please check for another input ?as i mention in comment on your answer.! Pranav C balans answer help me to resolve my question.but i want to learn your method also. – aryan Oct 12 '15 at 13:13

3 Answers3

7

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));
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
  • thanks for your Ans. @pranav .I will read once again about JSON.stringify +1 – aryan Oct 09 '15 at 11:17
  • @aryan : glad to help you :) . JSON.stringify is just for converting to string..... and showing the result – Pranav C Balan Oct 09 '15 at 11:22
  • what to do if i dont want to change the order of element? like given array [3,2,-1,0,-4,3,6,-7,-6] and sorted array [-1,-4,-7,-6,3,2,0,3,6] How can i achive that? – aryan Oct 09 '15 at 11:30
  • @aryan https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort – Pranav C Balan Oct 09 '15 at 11:31
  • I know about array.sort().it will give min. to max value. But how to achieve above array is my real question. – aryan Oct 09 '15 at 11:40
  • can you please tell me how to do it? – aryan Oct 09 '15 at 14:36
  • @aryan I COULDN'T GET YOU – Pranav C Balan Oct 09 '15 at 14:40
  • see , if i want to separate the elements without changing their relative position. like above example,negative numbers first-1 after -4 ,after -7 ,after -6 then positive number first come 3 after come 2 then come 0...likewise. sort() can sort the number but it provide small value to large value array. SO i asked. – aryan Oct 10 '15 at 06:42
  • Great..!!! but my mind is now bursting .when i go for another input like [3, 4, -6, 0, -8, -1, 3, -6, 1, -8, -6, -1] it is providing [-1,-6,-8,-1,-6,-8,-6,0,1,4,3,3] very different. here -1 coming at first place and positive numbers also change. I checked by changing the operators but output remain same. what to do now? – aryan Oct 10 '15 at 07:41
  • as I mentioned in question ,I don't want to use temp. array. here we are using pos and neg both temporary array . so is it not possible to do with single array only?? – aryan Oct 10 '15 at 09:01
  • @aryan : there is no other way to do that – Pranav C Balan Oct 10 '15 at 09:03
  • Your jsfiddle link taking too much time to load the program.It is not opening.Since half an hour i am trying to open it. will you check it please? – aryan Oct 10 '15 at 10:29
  • Thanks @Pranav..!It works...!!!! :) Right now i have got better understanding of arrays.!! – aryan Oct 12 '15 at 13:03
  • @aryan : glad to help :) – Pranav C Balan Oct 12 '15 at 13:04
1

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.

Community
  • 1
  • 1
  • Oh ..this is the new one..! it gives the correct ans for above array but when i go for another input like [3, 4, -6, 0, -8, -1, 3, -6, 1, -8, -6, -1] it is providing [-1,-6,-8,-1,-6,-8,-6,0,1,4,3,3] very different. here -1 coming at first place and positive numbers also change. Can you check with this array..? I have got ans for Pranav C Balan. – aryan Oct 12 '15 at 13:10
  • @torazaburo, maybe you know how can I sort `[-2, -1, 2, 3, -3]` in to `[2, 3, -3, -2, -1]`? i.e. first goes positive in ascending and after negative in descending – Edgar Jun 01 '17 at 22:56
0

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]
Vinod kumar G
  • 639
  • 6
  • 17