1
$\begingroup$

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

$\endgroup$
  • $\begingroup$ Have a look at Cases and Select. $\endgroup$ – b.gates.you.know.what Feb 25 '13 at 13:31
8
$\begingroup$
  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]
$\endgroup$
5
$\begingroup$

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}]
$\endgroup$
  • $\begingroup$ I'd stay with With[{mask = BitAnd[a, 1]}, Pick[a, mask, #] & /@ {0, 1}] $\endgroup$ – Rojo Feb 25 '13 at 20:28
  • $\begingroup$ @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. $\endgroup$ – Mr.Wizard Feb 26 '13 at 2:07
  • $\begingroup$ GatherBy: 1.6s, yours: 0.73, with pick and BitAnd, 0.56. Both in v8 and v9 $\endgroup$ – Rojo Feb 26 '13 at 12:30
  • $\begingroup$ @Rojo Okay, thanks. I added that to my answer. $\endgroup$ – Mr.Wizard Feb 26 '13 at 13:14
0
$\begingroup$

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}} *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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