我有一大组参数P,它们采用几组不同的值V_i,并希望使用ActionMenu[]
来轻松分配P = V_i,如下所示:
ActionMenu["Label", {"name_1" :> (P = V_1;),..}]
现在的问题是V_i的集合很大而不是静态的,所以我不想手动反复编写长列表{"opt_1" :> (P = V_1;),..}
,而是想生成它。
我完全不知道如何去做。一般方法类似于
Thread@RuleDelayed[listOfNames,listOfActions]
其中listOfActions
应该是
Thread@Set[repeatedListOfP,listOfV_i]
但这不起作用。由于Set[]
是一个非常特殊的函数,我的其他常用方法都不起作用(构建Table[]
,替换标题等)。您如何构建Set[]
操作列表?
答案 0 :(得分:2)
你的问题可能还有更多,我还没有讨论过,但也许这会让你走上正轨。
此
MapThread[Hold[#1 = #2]&, {{a, b, c}, {1, 2, 3}}]
返回未评估的“Set”列表,如下所示:
{Hold[a = 1], Hold[b = 2], Hold[c = 3]}
如果您在上面调用ReleaseHold,那么分配将实际发生。
更多关于暂停和亲戚的信息:
Mathematica: Unevaluated vs Defer vs Hold vs HoldForm vs HoldAllComplete vs etc etc
答案 1 :(得分:1)
这是我在想要有RuleDelayed
个具有副作用的应用程序时使用的替代解决方案。您使用不同的头代替Set
,直到您的表达位于RuleDelayed
表单的右侧(RuleDelayed
的{{1}} HoldRest
{ 1}}}}然后将Set
替换回来。当我这样做时,我喜欢使用Module
为我创建一个独特的符号。这样您就不必使用Defer
,这是一个比Unevaluated
更令人不快的构造。
以下是一个例子:
Module[{set},
Attributes[set] = Attributes[Set];
With[{rhs = MapThread[set, Unevaluated[{{x, y, z}, {1, 2, 3}}]]},
"name1" :> rhs /. {set -> Set, List -> CompoundExpression}]]
set
符号与Set
具有相同属性的原因以及Unevaluated
所在的原因是,即使有人已经分配了值,也要确保此功能正常工作到x
,y
或z
。
另一种可能性是将所有Set
表达式包装为闭包,然后在评估Scan
时使用RuleDelayed
来调用它们,如下所示:
With[{thunks = MapThread[Function[{a, b}, (a = b) &, HoldAll],
Unevaluated[{{x, y, z}, {1, 2, 3}}]]},
"name1" :> Scan[#[] &, thunks]]