# Subpartitioning elements of a list based on some h[ri] == h[rj] test

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?

GatherBy[ list, Mod[#, 3] &]

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

• Or Gather[list, Mod[#1, 3] == Mod[#2, 3] &] Dec 6, 2014 at 19:13

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}} *)