Function Repository Resource:

Unthread

Source Notebook

A partial inverse for Thread

Contributed by: Richard Hennigan (Wolfram Research)

ResourceFunction["Unthread"][f[g[a1,,an],g[b1,,bn],]]

"unthreads" g to return g[f[a1,b1,],,f[an,bn,]].

Details and Options

ResourceFunction["Unthread"] is a partial inverse for Thread.
In ResourceFunction["Unthread"][f[a1,a2,]], all of the ai must have the same Head.
In ResourceFunction["Unthread"][f[g[],g[],]], each of the g[] must have the same number of arguments.
ResourceFunction["Unthread"] has the following options:
"PreserveRepeats"Truewhether to preserve all repeating elements or flatten them

Examples

Basic Examples (3) 

Unthread f from a list:

In[1]:=
ResourceFunction["Unthread"][{f[a], f[b], f[c]}]
Out[1]=

Unthread a head with two arguments:

In[2]:=
ResourceFunction["Unthread"][{f[a, x], f[b, y], f[c, z]}]
Out[2]=

Convert lists of equations to equations for lists:

In[3]:=
ResourceFunction["Unthread"][{a == x, b == y, c == z}]
Out[3]=

Unthread a Thread:

In[4]:=
Thread[f[{a, b, c}]]
Out[4]=
In[5]:=
ResourceFunction["Unthread"][%]
Out[5]=
In[6]:=
Thread[Log[x == y], Equal]
Out[6]=
In[7]:=
ResourceFunction["Unthread"][%]
Out[7]=

Scope (1) 

Use Unevaluated to unthread an expression before it evaluates:

In[8]:=
ResourceFunction["Unthread"][Unevaluated[Echo[1] + Echo[2] + Echo[3]]]
Out[8]=

Options (2) 

PreserveRepeats (2) 

By default, repeating elements in the output of Unthread will all appear:

In[9]:=
expr = f[{a, b, c}, x]
Out[9]=
In[10]:=
threaded = Thread[expr]
Out[10]=
In[11]:=
ResourceFunction["Unthread"][threaded]
Out[11]=

In this case, Unthread can be coerced into being an inverse by setting "PreserveRepeats"False:

In[12]:=
ResourceFunction["Unthread"][threaded, "PreserveRepeats" -> False]
Out[12]=

Properties and Relations (3) 

Unthread is just another form of Thread, where the second argument is chosen automatically:

In[13]:=
expr = f[g[a, b, c], g[x, y, z]]
Out[13]=
In[14]:=
ResourceFunction["Unthread"][expr]
Out[14]=
In[15]:=
Thread[expr, g]
Out[15]=

Unthread is a generalization of Transpose:

In[16]:=
expr = {{a, b, c}, {x, y, z}}
Out[16]=
In[17]:=
Transpose[expr]
Out[17]=
In[18]:=
ResourceFunction["Unthread"][expr]
Out[18]=

Unthread is its own inverse:

In[19]:=
id = ResourceFunction["Unthread"]@*ResourceFunction["Unthread"]
Out[19]=
In[20]:=
id[{f[a], f[b], f[c]}]
Out[20]=
In[21]:=
id[{f[a, x, y], f[b, x, y], f[c, x, y]}]
Out[21]=
In[22]:=
id[{a == x, b == y, c == z}]
Out[22]=

Possible Issues (3) 

Unthread cannot always invert Thread, even when using "PreserveRepeats"False:

In[23]:=
expr = f[{a, b, c}, x, {y, y, y}]
Out[23]=
In[24]:=
threaded = Thread[expr]
Out[24]=
In[25]:=
ResourceFunction["Unthread"][threaded]
Out[25]=
In[26]:=
ResourceFunction["Unthread"][threaded, "PreserveRepeats" -> False]
Out[26]=

The inner expressions must have the same number of arguments:

In[27]:=
ResourceFunction["Unthread"][f[g[1, 2], g[1, 2, 3]]]
Out[27]=

The inner expressions must have the same Head:

In[28]:=
ResourceFunction["Unthread"][f[g[1, 2], h[3, 4]]]
Out[28]=

Requirements

Wolfram Language 11.3 (March 2018) or above

Version History

  • 1.0.0 – 18 February 2019

Related Resources

License Information