Index-based Array splitting
For the simple case of even and odd, you can do either:
{testArrayOdd, testArrayEven} = {testArray[[;; ;; 2]], testArray[[2 ;; ;; 2]]}
(* {{"String 1", "String 3", "String 5"}, {"String 2", "String 4"}} *)
or
{testArrayOdd, testArrayEven} = Partition[testArray, 2, 2, 1, {}] ~Flatten~ {2}
For a more general grouping based on an arbitrary predicate, you can write a custom function:
Clear@groupByPositions
groupByPositions[list_, pred_] :=
With[{trueList = testArray[[Select[Range@Length@list, pred]]]},
{trueList, Complement[list, trueList]}
]
With this, the original problem becomes
{testArrayOdd, testArrayEven} = groupByPositions[testArray, OddQ]
and to group by prime indices:
groupByPositions[testArray, PrimeQ]
(* {{"String 2", "String 3", "String 5"}, {"String 1", "String 4"}} *)
Just for the sake of variety:
MapIndexed
could be used here, in conjunction with tagged Sow
ing and Reap
ing:
Reap[MapIndexed[If[PrimeQ@First@#2, Sow[#1, 1], Sow[#1, 2]] &,
testArray]] // Last (* partition based on index primeness *)
(* {{"String 1", "String 4"}, {"String 2", "String 3", "String 5"}} *)
I've used the integers 1 and 2 as tags. (The docs show symbols like x
and y
being used, but integers appear to work OK too.)
The list associated with the first tag to be encountered is given first, hence the order of the sublists above. If you wished to change that, you could add {2, 1}
as an extra argument at the end of Reap
.
(As Mr. Wizard suggests in his comment, a better expression is:
Reap[MapIndexed[# ~Sow~ PrimeQ[#2] &, testArray]][[2]]
where the tag is automatically generated as the predicate's value and the If
is completely avoided.)
Personally I find GatherBy
most natural here:
Part[testArray, #] & /@ GatherBy[Range@Length@testArray, PrimeQ]
You could use my GatherByList
function to do this:
GatherByList[list_, representatives_] := Module[{func},
func /: Map[func, _] := representatives;
GatherBy[list, func]
]
GatherByList[testArray, EvenQ[Range @ Length @ testArray]]
GatherByList[testArray, PrimeQ[Range @ Length @ testArray]]
{{"String A", "String C", "String E"}, {"String B", "String D"}}
{{"String A", "String D"}, {"String B", "String C", "String E"}}