Wolfram Research

Function Repository Resource:

ReapAssociation

Source Notebook

Equivalent to Reap, but returns an association with tags as keys

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["ReapAssociation"][expr]

gives the value of expr together with all expressions to which Sow has been applied during its evaluation. Expressions sown using Sow[e] or Sow[e,tagi] with different tags are returned as lists in an association keyed by the tags.

ResourceFunction["ReapAssociation"][expr,patt]

reaps only expressions sown with tags that match patt.

ResourceFunction["ReapAssociation"][expr,{patt1,patt2,}]

puts expressions associated with each of the patti in a separate list.

ResourceFunction["ReapAssociation"][expr,patt,f]

has values f[tagi(ei,1,ei,2,...}] for each key tagi.

Details and Options

Sow and ResourceFunction["ReapAssociation"] provide a convenient way to accumulate a list of intermediate results in a computation.
ResourceFunction["ReapAssociation"] accumulates expressions in the order in which Sow is applied to them.
Expressions sown with a particular tag are collected by the innermost ResourceFunction["ReapAssociation"] whose pattern matches the tag.
Expressions sown with no tag are returned using the tag None.
The result of evaluating the expression is returned using the key "Result", and the sown values are in an association under the key "Sown".
ResourceFunction["ReapAssociation"][expr] is equivalent to ResourceFunction["ReapAssociation"][expr,_].
ResourceFunction["ReapAssociation"] has attribute HoldFirst.

Examples

Basic Examples

Evaluate a sequence of expressions, "reaping" ones that have been "sown":

In[1]:=
ResourceFunction["ReapAssociation"][Sow[a]; b; Sow[c]; Sow[d]; e]
Out[1]=

Compute a sum, "reaping" i^2 "sown" at each step:

In[2]:=
ResourceFunction["ReapAssociation"][Sum[Sow[i^2] + 1, {i, 10}]]
Out[2]=

Make a separate key for each tag being reaped:

In[3]:=
ResourceFunction["ReapAssociation"][Sow[1, x]; Sow[2, y]; Sow[3, {x, y}]]
Out[3]=
In[4]:=
ResourceFunction["ReapAssociation"][Table[Sow[i, OddQ[i]], {i, 10}]]
Out[4]=
In[5]:=
ResourceFunction["ReapAssociation"][
 Do[Sow[i, If[PrimeQ[i], "Prime", "Composite"]], {i, 2, 100}]]
Out[5]=

Scope

If nothing is sown, an empty association will be returned in the "Sown" key:

In[6]:=
ResourceFunction["ReapAssociation"][1 + 1]
Out[6]=

Count the number of instances of each integer, separating the negative:

In[7]:=
ResourceFunction["ReapAssociation"][
 Sow[1, RandomInteger[{-9, 9}, 100]], {_?Negative, _?NonNegative}, Total[#2] &]
Out[7]=

Generalizations & Extensions

Apply f to each distinct key and list of values:

In[8]:=
ResourceFunction["ReapAssociation"][Sow[1, {x, x}]; Sow[2, y]; Sow[3, x], _, f]
Out[8]=
In[9]:=
ResourceFunction["ReapAssociation"][Sow[1, x]; Sow[2, y]; Sow[3, x], _, Echo[#2, #1] &]
Out[9]=

Applications

Find the list of values sampled by Plot:

In[10]:=
ResourceFunction["ReapAssociation"][
 Plot[Sin[x], {x, 0, 10}, EvaluationMonitor :> Sow[x]], _, Short[#2, 5] &]
Out[10]=

Remove duplicates from a list, keeping the original order:

In[11]:=
unsortedUnion[x_] := Keys[Lookup[ResourceFunction["ReapAssociation"][Sow[1, x]], "Sown"]]
In[12]:=
unsortedUnion[{b, b, c, a, c, a, b, d}]
Out[12]=

This is like Union without the sorting:

In[13]:=
Union[{b, b, c, a, c, a, b, d}]
Out[13]=

Properties & Relations

If no expressions are sown, ReapAssociation returns an empty association of expressions it has reaped:

In[14]:=
ResourceFunction["ReapAssociation"][x]
Out[14]=

ReapAssociation collects expressions in exactly the order they are sown:

In[15]:=
ResourceFunction["ReapAssociation"][MapAll[Sow, (a + b) (c + x^2)];]
Out[15]=

The list associated with the first tag to be encountered will be the first key:

In[16]:=
ResourceFunction["ReapAssociation"][Sow[1, y]; Sow[2, x]; Sow[3, y]]
Out[16]=

When the order of tags is not known, ReapAssociation can make it easier to understand results compared to Reap:

In[17]:=
SeedRandom[1];
Reap[Table[Sow[i, RandomChoice[{"a", "b", "c"}]], {i, 20}]] // Last
Out[7]=
In[18]:=
SeedRandom[1];
ResourceFunction["ReapAssociation"][
  Table[Sow[i, RandomChoice[{"a", "b", "c"}]], {i, 20}]] // Last
Out[10]=

Neat Examples

Create an animation showing the full stack history of an evaluation:

In[19]:=
fib[0] := 1;
fib[1] := 1;
fib[n_] := fib[n - 2] + fib[n - 1];
In[20]:=
ListAnimate[
 DeleteDuplicates[
  ResourceFunction["ReapAssociation"][
    StackBegin[
     TraceScan[StackInhibit[Sow[Column[Rest[Stack[_]]], "fib"]] &, Table[fib[i], {i, 5}]]]][["Sown", "fib"]]]]
Out[20]=

Requirements

Wolfram Language 11.3 (March 2018) or above

Resource History

See Also

License Information