2

If we have a list of elements:

list = {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12};

I'd like to further partition the elements into sets where, for some function h it will always be the case that h[ri] == h[rj] (i and j being any pair of indices for elements in the set). I can also promise that it will always be that case h[ri] != h[rj] if ri and rj are from two distinct such subpartitionings.

For example, we could write:

list = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

And we could ask for a partitioning of the elements based on h := Mod[#, 3] &, which would then give the subpartitioning:

list = {{3, 6, 9, 12}, {1, 4, 7, 10}, {2, 5, 8, 11}};

Is there a neat way to do this for an arbitrary test function in Mathematica?

SShepard
  • 117
  • 3

2 Answers2

2
GatherBy[ list, Mod[#, 3] &]
{{1, 4, 7, 10}, {2, 5, 8, 11}, {3, 6, 9, 12}}
Artes
  • 57,212
  • 12
  • 157
  • 245
1

You can also use the Version 10 built-in GroupBy. It can be invoked in two ways:

list = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

Values@GroupBy[list,Mod[#,3]&]
(* {{1, 4, 7, 10}, {2, 5, 8, 11}, {3, 6, 9, 12}} *)

Values@GroupBy[Mod[#,3]&]@list
(* {{1, 4, 7, 10}, {2, 5, 8, 11}, {3, 6, 9, 12}} *)
kglr
  • 394,356
  • 18
  • 477
  • 896