Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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

share|improve this question
    
Have a look at Cases and Select. –  b.gatessucks Feb 25 '13 at 13:31
add comment

3 Answers

up vote 7 down vote accepted
  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]
share|improve this answer
add comment

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];

With[{mask = BitAnd[a, 1]},
  {a[[ SparseArray[mask, Automatic, 1]["AdjacencyLists"] ]],
   a[[ SparseArray[mask]["AdjacencyLists"] ]]}
] // 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}]
share|improve this answer
    
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
add comment

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}} *)
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.