-1

Suppose I have an array:

var ay=[0,1,2,3,4,5,6,7,8,9];

Now I want to get two array:

var ay1=[0,2,4,6,8];
var ay2=[1,3,5,7,9];

What is efficient way?


Update:

I know the simple loop and modulo operator method(as elclanrs said) like this:

var ay1=[],ay2=[];
for(var i=0,len=ay.length;i++){
  if(i%2==0){
    ay2.push(ay[i]);
  } else 
    ay1.push(ay[i]);
}

But I just wonder if there is any other efficient or cool way I do not know yet.

That is why I ask this simple question. I am not asking how to do , I am asking how to do better if possible!

So I do not think this post deserved the down-votes.

hguser
  • 35,079
  • 54
  • 159
  • 293

8 Answers8

5

Let's say we generalize this problem a bit. Instead of just splitting an array's alternating elements into two arrays, why not allow for the array to be split in the same way into three, four, or more individual arrays?

It turns out it's about as easy to allow for any number of arrays as it is to do just two.

Think of the array like a rope made up of strands, and whatever number of strands you have in the rope, you want to unravel it. You could do it like this:

// "Unravel" an array as if it were a rope made up of strands, going
// around the rope and pulling off part of each strand one by one.
// 'rope' is the array and 'count' is the number of strands.
// Return an array of arrays, where the outer array has length 'count'
// and the inner arrays represent the individual strands.
function unravel( rope, count ) {
    // Create each strand
    var strands = [];
    for( var i = 0;  i < count;  i++ ) {
        strands.push( [] );
    }
    // Unravel the rope into the individual strands
    for( var i = 0, n = rope.length;  i < n;  i++ ) {
        strands[ i % count ].push( rope[i] );
    }
    return strands;
}

var rope = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];

var s = unravel( rope, 2 );
console.log( s[0], s[1] );

var s = unravel( rope, 3 );
console.log( s[0], s[1], s[2] );

var s = unravel( rope, 5 );
console.log( s[0], s[1], s[2], s[3], s[4] );

This logs:

[0, 2, 4, 6, 8] [1, 3, 5, 7, 9]
[0, 3, 6, 9] [1, 4, 7] [2, 5, 8]
[0, 5] [1, 6] [2, 7] [3, 8] [4, 9]

Note that in the second case (count=3) one of the strands is longer than the other two—which is to be expected since 10 is not evenly divisible by 3.

Michael Geary
  • 28,450
  • 9
  • 65
  • 75
  • 1
    @D80Buckeye - Yes, you do have a point there. But wait: you haven't seen my version of Enterprise FizzBuzz! – Michael Geary Jun 20 '13 at 04:44
  • @MichaelGeary: This is funny. :) – hguser Jun 20 '13 at 05:32
  • @hguser - Thanks! If all else fails, there is always my [jQuery arithmetic plugin](http://www.reddit.com/r/programming/comments/buosj/add_a_number_to_another_number_in_javascript_img/). (OTOH, the `unbraid` code in this answer isn't intended as that kind of humor - it seems like a fairly reasonable extension of the original idea.) – Michael Geary Jun 20 '13 at 05:42
0

Why not use a modulus function?

for (var i = 0; i < ay.length; i++) {
    if (i%2 == 0)
    {
     ay1[i] = ay[i];
    }
    else
    {
     ay2[i] - ay[i];
    }
}
Dan
  • 5,153
  • 4
  • 31
  • 42
0

Here's one way:

var ay = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

var ay1 = [];
var ay2 = [];
for(var i = 0; i < ay.length; i++) {
    if(i % 2 == 0) {
        ay1.push(ay[i]);
    }else{
        ay2.push(ay[i]);
    }
}
0
var ay=[0,1,2,3,4,5,6,7,8,9];
var ay1 = [];
var ay2 = [];

for (var i = 0; i < ay.length; i++)
    if (i % 2) ay2.push(ay[i]);
    else ay1.push(ay[i]);
console.log(ay1, ay2);

http://jsfiddle.net/MPAAC/

Antoine
  • 2,785
  • 1
  • 16
  • 23
0
var ay1=new Array();
var ay2=new Array();

for (var i = 0, len = ay.length; i < len; i++) {
//Check the i is odd or even
//insert any one of the array

}
sunleo
  • 10,589
  • 35
  • 116
  • 196
0

Why not use the array's filter method?

var ay = [0,1,2,3,4,5,6,7,8,9];
var odds = ay.filter(function(val){ return val % 2 === 1; });
var evens = ay.filter(function(val){ return val % 2 === 0; });

With a shim from the above link being available if you need to support IE8

Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
0

Here is a variant, just because I can. Is it "the most efficient"? Heck no; but it has the same bounds - O(1) for a constant-sized number of result lists.

It's cool and super flexible - it's really just a "partition" variant that can unzip to n (possibly non-distinct) sequences. Most other answers given are all based on a specialized partition implementation that doesn't utilize a HoF, so I consider this superior in that aspect ;-) It should be a good exercise to work through how this works.

function unzip(arr) {
    var conds = Array.prototype.slice.call(arguments, 1);
    // Requires ES5 or a shim for `Array.map`.
    var res = conds.map(function () { return [] });
    for (var i = 0; i < arr.length; i++) {
       for (var k = 0; k < conds.length; k++) {
           if (conds[k](i, arr[i])) {
               res[k].push(arr[i]);
           }
       }
    }
    return res;
}

r = unzip([0,1,2,3,4],
    function (i) { return !(i % 2) }, // even
    function (i) { return i % 2 });   // odd

alert(r[0] + " || " + r[1]);

If underscore.js is already being used (why not?) then a groupBy approach can be used.

Community
  • 1
  • 1
Paul
  • 247
  • 1
  • 4
0
funciton isEven(x) {
   return x % 2 == 0;
}
function isOdd(x) {
   return ! isEven(x);
}

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
    arrEven = arr.filter(isEven),
    arrOdd = arr.filter(isOdd);
LiuLang
  • 773
  • 4
  • 4