Wolfram Research

Function Repository Resource:

JoinRest

Source Notebook

An operator that performs a Join of its argument with the sequence of lists it is provided

Contributed by: Seth J. Chandler

ResourceFunction["JoinRest"][list]

gives an operator that will join list with the sequence of lists it is given.

Details and Options

When used in conjunction with associations, ResourceFunction["JoinRest"] can be thought of as creating an association of key-value pairs kv that will augment the output association if and only if the Join of whatever arguments the operator encounters fail to otherwise contain a key-value pair with a key of k.
The argument need not have head List. All subsequent expressions will be joined to it, provided they have the same head.

Examples

Basic Examples

JoinRest uses Join to join its argument {3,4} with whatever else it encounters, which you may think of as the “Rest” of the Join:

In[1]:=
ResourceFunction["JoinRest"][{3, 4}][{5, 6, 7}, {8, 9, 10, 11}]
Out[1]=

JoinRest applied to an association creates an operator that will add key-value pairs to the Join of the argument it is passed, but only if those joined associations fail to contain a key present in the association to which JoinRest was applied:

In[2]:=
ResourceFunction["JoinRest"][<|"a" -> 0, "b" -> 0, "c" -> 0|>][
 Association["a" -> 7, "b" -> 9]]
Out[2]=

Scope

The operator created by JoinRest using an Association can accept a sequence of associations:

In[3]:=
ResourceFunction["JoinRest"][<|"a" -> 0, "b" -> 0, "c" -> 0|>][
 Association["a" -> 7, "b" -> 9], Association["a" -> -8, "c" -> 3]]
Out[3]=

If JoinRest has no argument, it operates as an identity on the data it is given:

In[4]:=
ResourceFunction["JoinRest"][][Association["a" -> 7, "b" -> 9]]
Out[4]=

If JoinRest has a sequence of associations as its argument, it will use the last value for any key it encounters in that sequence as a basis for adding key-value pairs:

In[5]:=
ResourceFunction["JoinRest"][<|"a" -> 0|>, <|"a" -> 4, "c" -> -2|>][
 Association["b" -> 9], Association["b" -> -8, "c" -> 3]]
Out[5]=

Applications

JoinRest can be right-composed with Counts to create an Association that obtains the number of every anticipated value in an expression:

In[6]:=
Query[Counts /* ResourceFunction[
    "JoinRest"][<|"a" -> 0, "b" -> 0, "c" -> 0|>]][{"a", "b", "a", "b", "a", "a", "a", "b"}]
Out[6]=

Properties and Relations

JoinRest works similarly to Merge with a First combiner function:

In[7]:=
With[{data = {"a", "b", "a", "b", "a", "a", "a", "b"}, default = <|"a" -> 0, "b" -> 0, "c" -> 0|>}, SameQ[Query[Counts /* ResourceFunction["JoinRest"][default]][data], Merge[{Query[Counts][data], default}, First]
  ]
 ]
Out[7]=

JoinRest is very similar to the resource function JoinMost. In JoinRest its argument is placed first in the Join; in JoinMost its argument is placed last in the Join.

Possible Issues

JoinRest, like Join, will fail to evaluate if the heads of the expressions to be joined differ from one another:

In[8]:=
ResourceFunction["JoinRest"][{1, 2, 3}][Association["a" -> 2]]
Out[8]=

Neat Examples

Insert JoinRest into a pipeline of operators created by Query, such that the count of various categories that survived and died on the Titanic defaults to 0:

In[9]:=
formatting = Row[{Labeled[#1, "ugly"], Labeled[#2, "nicer"]}, Spacer[6]] &;
In[10]:=
Module[{noMaleSurvivors = Query[Select[Not[#sex === "male" && #survived] &]][
    ExampleData[{"Dataset", "Titanic"}]], uglyQuery, prettyQuery, survivedString = (If[#survived, "survived", "died"] &), f1 = GroupBy[#class &], f2 = GroupBy[#sex &] /* KeySort,
  f3 = Counts /* KeySort,
  joiner = ResourceFunction["JoinRest"][
    Association["survived" -> 0, "died" -> 0]]},
 uglyQuery = Query[f1, f2, f3, survivedString];
 prettyQuery = Query[f1, f2, Insert[f3, joiner, 2], survivedString]; formatting[uglyQuery[noMaleSurvivors], prettyQuery[noMaleSurvivors]]
 ]
Out[10]=

Resource History

See Also

License Information