Message Boards Message Boards

12 Replies
30 Total Likes
View groups...
Share this post:

Distributing a list of heads over a list of arguments

Posted 11 years ago
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]}
POSTED BY: Vitaliy Kaurov
12 Replies
#[[1]][#[[2]]] & /@ Transpose[{heads, arguments}]
Compose@@@Thread@{heads, arguments}
POSTED BY: Rodrigo Murta
Dot[heads, arguments] /. Times -> (Operate[##, 0] &)
POSTED BY: Arnoud Buzing
Posted 11 years ago
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]
POSTED BY: Itai Seggev
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.
POSTED BY: Brett Champion
Posted 11 years ago
No worries, but for the inconvenience you have to suffer reading this code, in the category:
Way clumsier

result = {};
  i = 1,
  i <= Max[Length /@ {heads, arguments}],
  i += Length[IntegerPartitions[i]]/PartitionsP[i],
  AppendTo[result, heads[[i]][arguments[[i]]]]
POSTED BY: Simon Schmidt
@Simon Schmidt - Wow this is a real fun one ;-)  +1 !
POSTED BY: Vitaliy Kaurov
Posted 11 years ago
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]
POSTED BY: Simon Schmidt
In[1]:= Inner[#1[#2] &, heads, arguments, List]
Out[1]= {f[w], g[x], h[y], k[z]}
POSTED BY: Daniel Lichtblau
Compose is currently superseded by composition, but that works slightly different, so another solution is:
MapThread[#1@#2 &, {heads,arguments}]
POSTED BY: Sander Huisman
Posted 11 years ago
Sander Huisman, - this would be my solution as well.
POSTED BY: Itai Seggev
MapThread[Compose, {heads, arguments}]
POSTED BY: Ilian Gachevski
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract