Suppose I've defined a list of variables
{a,b,c} = {1,2,3}
If I want to double them all I can do t开发者_Python百科his:
{a,b,c} *= 2
The variables {a,b,c} now evaluate to {2,4,6}. If I want to apply an arbitrary transformation function to them, I can do this:
{a,b,c} = f /@ {a,b,c}
How would you do that without specifying the list of variables twice?
(Set aside the objection that I'd probably want an array rather than a list of distinctly named variables.)
You can do this:
Function[Null, # = f /@ #, HoldAll][{a, b, c}]
For example,
In[1]:=
{a,b,c}={1,2,3};
Function[Null, #=f/@#,HoldAll][{a,b,c}];
{a,b,c}
Out[3]= {f[1],f[2],f[3]}
Or, you can do the same without hard-coding f
, but defining a custom set
function. The effect of your foreach loop can be reproduced easily if you give it Listable attribute:
ClearAll[set];
SetAttributes[set, {HoldFirst, Listable}]
set[var_, f_] := var = f[var];
Example:
In[10]:= {a,b,c}={1,2,3};
set[{a,b,c},f1];
{a,b,c}
Out[12]= {f1[1],f1[2],f1[3]}
You may also want to get speed benefits for cases when your f
is Listable, which is especially relevant now since M8 Compile enables user-defined functions to benefit from being Listabe in terms of speed, in a way that previously only built-in functions could. All you have to do for set
for such cases (when you are after speed and you know that f
is Listable) is to remove the Listable attribute of set
.
I hit upon an answer to this when fixing up this old question: ForEach loop in Mathematica
Defining the each
function as in the accepted answer to that question, we can answer this question with:
each[i_, {a,b,c}, i = f[i]]
精彩评论