开发者

How to construct a list of Set's

I have a large set of parameters P which take several distinct sets of values V_i and want to use ActionMenu[] to make assigning P=V_i easy, like so:

ActionMenu["Label", {"name_1" :> (P = V_1;),..}]

Now the problem is that the set of V_i's is large and not static, so instead of coding a long list {"opt_1" :> (P = V_1;),..} over and over by hand, I'd like to generate it.

I am completely stumped at how to do it. The general approach is something like

Thread@RuleDelayed[listOfNames,listOfActions]

where listOfActions should be something like

Thread@Set[repeatedListOfP,listOfV_i]

But this does not work. And since Set[] is a very special function, none of my other usu开发者_如何学运维al approaches work (building a Table[], replacing headers, etc). How do you go about constructing a list of Set[] operations?


There may be more to your question that I haven't grokked yet but maybe this will get you on the right track.

This

MapThread[Hold[#1 = #2]&, {{a, b, c}, {1, 2, 3}}]

returns a list of unevaluated "Set"s like so:

{Hold[a = 1], Hold[b = 2], Hold[c = 3]}

If you call ReleaseHold on the above then the assignments will actually happen.

More on Hold and relatives here:
Mathematica: Unevaluated vs Defer vs Hold vs HoldForm vs HoldAllComplete vs etc etc


Here's an alternative solution that I've used when I've wanted to have RuleDelayed applications that have side-effects. You use a different head to substitute in for Set until you have your expression on the right-hand side of a RuleDelayed form (where it'll be held by RuleDelayed's HoldRest attribute) and then subsitute Set back in. When I do this, I like to use Module to create a unique symbol for me. This way you don't have to use Defer, which is an even more unpleasantly slippery construct than Unevaluated.

Here's an example:

Module[{set},
 Attributes[set] = Attributes[Set];

 With[{rhs = MapThread[set, Unevaluated[{{x, y, z}, {1, 2, 3}}]]},
  "name1" :> rhs /. {set -> Set, List -> CompoundExpression}]]

The reason the set symbol is given the same attributes as Set, and the reason the Unevaluated is there, is to make sure this works even if someone has already assigned a value to x, y or z.

Another possibility is to wrap all your Set expressions up as closures and then use Scan to call them when the RuleDelayed is evaluated, like so:

With[{thunks = MapThread[Function[{a, b}, (a = b) &, HoldAll],
    Unevaluated[{{x, y, z}, {1, 2, 3}}]]},
 "name1" :> Scan[#[] &, thunks]]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜