# Separate an array in two arrays, the even and odd terms being separated in these two arrays

How can I separate the odd terms in one array and the even terms in another array,i.e., go from

a={1,2,3,4}


to

aeven={2,4} and aodd={1,3}

I thought of:

a={1,2,3,4}

s={}

For[i = 1, i <= 4, i++,
If[EvenQ[a[[i]]] == True, AppendTo[a[[i]], s]]]


but it does not work.

Thankyou

-
Have a look at Cases and Select. – b.gatessucks Feb 25 '13 at 13:31

  GatherBy[a, OddQ]
(* {{1, 3}, {2, 4}} *)


or

 Pick[a, # /@ a] & /@ {OddQ, EvenQ}


or

 Pick[a, OddQ /@ a, #] & /@ {True, False}


or

 Cases[a, _?#] & /@ {OddQ, EvenQ}


or

 Select[a, #] & /@ {OddQ, EvenQ}


or

 SplitBy[SortBy[a, EvenQ], EvenQ]

-

kguler already showed the primary methods so here are some secondary ones.

One for fun:

a = Range@10;

Reap[Sow[#, #~Mod~2] & /@ a, {0, 1}][[2, All, 1]]

{{2, 4, 6, 8, 10}, {1, 3, 5, 7, 9}}


And one for performance:

a = RandomInteger[1*^7, 1*^7];

] // Timing // First

0.234


kguler's fastest method for comparison:

GatherBy[a, OddQ] // Timing // First

0.406


A fast method from Rojo for Mathematica versions 8+ (Pick was optimized after v7):

With[{mask = BitAnd[a, 1]}, Pick[a, mask, #] & /@ {0, 1}]

-
I'd stay with With[{mask = BitAnd[a, 1]}, Pick[a, mask, #] & /@ {0, 1}] – Rojo Feb 25 '13 at 20:28
@Rojo That's significantly slower in version 7. Is it better in v8/v9? I recall Leonid saying that Pick had been optimized for packed arrays after v7. – Mr.Wizard Feb 26 '13 at 2:07
GatherBy: 1.6s, yours: 0.73, with pick and BitAnd, 0.56. Both in v8 and v9 – Rojo Feb 26 '13 at 12:30
@Rojo Okay, thanks. I added that to my answer. – Mr.Wizard Feb 26 '13 at 13:14

I would go with one of the other options, but it can be done with Part and Span, as follows:

dat = Range[10];
{dat[[;; ;; 2]], dat[[2 ;; ;; 2]]}
(* {{1, 3, 5, 7, 9}, {2, 4, 6, 8, 10}} *)

-