Given two lists, one for the heads another for their arguments
heads = {f, g, h, k};
arguments = {w, x, y, z};
is there less clumsy way to do this?
In[1]:= Diagonal[Through /@ Distribute[heads[arguments], List]]
Out[1]= {f[w], g[x], h[y], k[z]}
Given two lists, one for the heads another for their arguments
heads = {f, g, h, k};
arguments = {w, x, y, z};
is there less clumsy way to do this?
In[1]:= Diagonal[Through /@ Distribute[heads[arguments], List]]
Out[1]= {f[w], g[x], h[y], k[z]}
Perhaps
MapThread[Compose, {heads, arguments}]
Compose is currently superseded by composition, but that works slightly different, so another solution is:
MapThread[#1@#2 &, {heads,arguments}]
In[1]:= Inner[#1[#2] &, heads, arguments, List]
Out[1]= {f[w], g[x], h[y], k[z]}
Sander Huisman, - this would be my solution as well.
Some more just for fun
(* Clearly that? is a transpose symbol *)
{heads, arguments}?/. {f_, a_} :> f@a
(* Listability is *always* good *)
Attributes[headThread] = {Listable};
headThread[f_, a_] := f@a;
headThread[heads, arguments]
(* .. especially in pure functions *)
Function[, #1@#2, {Listable}][heads, arguments]
No worries, but for the inconvenience you have to suffer reading this code, in the category:
Way clumsier
result = {};
For[
i = 1,
i <= Max[Length /@ {heads, arguments}],
i += Length[IntegerPartitions[i]]/PartitionsP[i],
AppendTo[result, heads[[i]][arguments[[i]]]]
];
result
@Simon Schmidt - Wow this is a real fun one
+1 !
Dot[heads, arguments] /. Times -> (Operate[##, 0] &)
Nice, but the Operate is slightly heavy handed. I think the following is both shorter and easier to understand:
In[7]:= Dot[heads, arguments] /. Times -> (#1[#2] &)
Out[7]= f[w] + g[x] + h[y] + k[z]
Of course, this will break if one of the arguments has head Times.
arguments = {w, x, y, z b};
In[18]:= Dot[heads, arguments] /. Times -> (Operate[##, 0] &)
During evaluation of In[18]:= Operate::argt: Operate called with 4 arguments; 2 or 3 arguments are expected. >>
Out[18]= f[w] + g[x] + h[y] + Operate[b, k, z, 0]
In[19]:= Dot[heads, arguments] /. Times -> (#1[#2] &)
Out[19]= b[k] + f[w] + g[x] + h[y]
In[7]:= Dot[heads, arguments] /. Times → (#1[#2] &)
Out[7]= f + g + h + k
Of course, this will break if one of the arguments has head Times.
And while it’s frequently safer to use Replace at a specific level is rather than ReplaceAll (/.) in code, even that won’t help you in this case. That’s probably why Dan’s answer used Inner instead of Dot.
Compose@@@Thread@{heads, arguments}
#[[1]][#[[2]]] & /@ Transpose[{heads, arguments}]