Elegant way for element-wise application of a list of functions
Let lst1 be the list of heads of your functions:
lst1={f,g,h};
for example they may be Cos
, Sin
, Exp
and so on, and lst2 is the list of numbers to which you want to apply the heads:
lst2={a,b,c};
A most simple way seems me to be this:
Transpose[{lst1, lst2}] /. {x_, y_} -> x[y]
(* {f[a], g[b], h[c]} *)
Another way would be to first introduce a function:
s[x_, y_] := x[y]
and with its use do this:
MapThread[s, {lst1, lst2}]
(* {f[a], g[b], h[c]} *)
or this:
Inner[s, lst1, lst2, List]
{f[a], g[b], h[c]}
One can probably find something else, but in the moment I do not see.
Have fun!
I think the MapThread
approach is already elegant. Anyway, the following is the shortest solution so far:
#@#2 & @@@ ArcTan[{f, g}, #] &
One can use the Listable
attribute to apply a list of function to lists of arguments. One can extend it easily to multiple lists of arguments (see last example).
Either via Function
:
Function[{x, y}, x[y], Listable][{f, g, h}, {x, y, z}]
(* {f[x], g[y], h[z]} *)
Or via a symbol:
Block[{threadApply},
SetAttributes[threadApply, Listable];
threadApply[f_, x___] := f[x];
threadApply[{f, g, h}, {x, y, z}]
]
(* {f[x], g[y], h[z]} *)
With the symbolic form, it's easy to deal with an arbitrary number of arguments:
Block[{threadApply},
SetAttributes[threadApply, Listable];
threadApply[f_, x___] := f[x];
threadApply[{f, g, h}, {a, b, c}, {x, y, z}]
]
(* {f[a, x], g[b, y], h[c, z]} *)
Block[{threadApply},
SetAttributes[threadApply, Listable];
threadApply[f_, x___] := f[x];
threadApply[{f, g, h}]
]
(* {f[], g[], h[]} *)
This is also possible with a slight modification of the OP's original MapThread
:
MapThread[#1[##2] &, {{f, g, h}, {a, b, c}, {x, y, z}}]
(* {f[a, x], g[b, y], h[c, z]} *)