# How to control which list Sow puts elements in

I'm trying to Reap/Sow elements of a list into separate sub-lists. In this toy example, I want evens in one list, odds in the other. But whichever sub-list d[[1]] happened to belong in, that sub-list comes first in Reap's output. If I wanted the even list to come first, I have to retest and reorder the sub-lists after Reap is finished. That isn't so bad when (as in the example) there are only two sub-lists, but in a bigger problem I have 20+ attributes with corresponding sub-lists! Is there a way to control what order Reap puts sub-lists in?

This works but is clunky and inefficient:

d = RandomInteger[100, 100];  (* Synthetic data *)
r = Reap[Do[If[EvenQ[d[[i]]], Sow[d[[i]], 1], Sow[d[[i]], 2]], {i, 1, Length[d]}]][[2]];
If[! EvenQ[r[[1, 1]]], r = {r[[2]], r[[1]]}]; (* Annoying that I have to do this to make the even list come first. *)
r

• Why not use the 2-argument form of Reap? Reap[ Sow[5, b]; Sow[4, a]; Sow[7, c]; Sow[8, b]; , {a, b, c, d}] for example Dec 7, 2018 at 19:55
• @JasonB. Thanks. Post this as an Answer, and I'll Accept it. Dec 7, 2018 at 20:20

The 2-argument form of Reap allows you to control the order of the output:

Reap[
Sow[5, b];
Sow[4, a];
Sow[7, c];
Sow[8, b];
5,
{a, b, c, d}
]
(* {5, {{{4}}, {{5, 8}}, {{7}}, {}}} *)


The 3-argument form gives even more control:

Reap[
Sow[5, b];
Sow[4, a];
Sow[7, c];
Sow[8, b];
5,
{a, b, c, d},
Rule
]
(* {5, {{a -> {4}}, {b -> {5, 8}}, {c -> {7}}, {}}} *)


Why not use GroupBy instead of Reap/Sow? For your example:

r = GroupBy[d,EvenQ]


<|True -> {80, 14, 0, 100, 68, 74, 24, 4, 100, 90, 70, 30, 48, 44, 56, 28, 68, 26, 68, 10, 86, 76, 44, 86, 18, 38, 30, 54, 4, 6, 2, 34, 18, 6, 6, 30, 60, 80, 56, 50, 58, 94, 92, 88}, False -> {67, 3, 65, 23, 97, 15, 83, 1, 25, 73, 69, 47, 43, 33, 93, 29, 75, 17, 45, 43, 79, 17, 43, 87, 51, 41, 15, 45, 99, 81, 39, 13, 41, 27, 7, 5, 3, 55, 81, 59, 25, 9, 91, 1, 47, 77, 25, 65, 61, 53, 61, 13, 63, 63, 91, 17}|>

If you just want the values, you can do:

Lookup[r, {True, False}]


{{80, 14, 0, 100, 68, 74, 24, 4, 100, 90, 70, 30, 48, 44, 56, 28, 68, 26, 68, 10, 86, 76, 44, 86, 18, 38, 30, 54, 4, 6, 2, 34, 18, 6, 6, 30, 60, 80, 56, 50, 58, 94, 92, 88}, {67, 3, 65, 23, 97, 15, 83, 1, 25, 73, 69, 47, 43, 33, 93, 29, 75, 17, 45, 43, 79, 17, 43, 87, 51, 41, 15, 45, 99, 81, 39, 13, 41, 27, 7, 5, 3, 55, 81, 59, 25, 9, 91, 1, 47, 77, 25, 65, 61, 53, 61, 13, 63, 63, 91, 17}}