2010-06-04 9 views
3

J'ai un grand nombre de paramètres P qui prennent plusieurs ensembles de valeurs distinctes v_i et que vous souhaitez utiliser ActionMenu[] pour faire assigner P = v_i facile, comme ceci:Comment construire une liste de Set de

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

maintenant le problème est que l'ensemble de V_i est grand et pas statique, donc au lieu de coder une longue liste {"opt_1" :> (P = V_1;),..} encore et encore à la main, je voudrais le générer.

Je suis complètement perplexe sur la façon de le faire. L'approche générale est quelque chose comme

[email protected][listOfNames,listOfActions] 

listOfActions devrait être quelque chose comme

[email protected][repeatedListOfP,listOfV_i] 

Mais cela ne fonctionne pas. Et puisque Set[] est une fonction très spéciale, aucune de mes autres approches habituelles ne fonctionne (construction d'un Table[], remplacement des en-têtes, etc.). Comment allez-vous construire une liste de Set[] opérations?

+0

Pourriez-vous distiller la partie ActionMenu de cela, si c'est pas fondamental à la question? – dreeves

+0

Oui, en attendant, j'ai résolu ce problème en utilisant SetterBar et Dynamic, ce qui est esthétiquement plus agréable de toute façon. Toujours intéressé par obtenir une liste des opérations Set [] cependant. – Timo

Répondre

2

Il se peut qu'il y ait plus à votre question que je n'ai pas encore fait de grokk mais peut-être que cela vous mettra sur la bonne voie.

Ce

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

retourne une liste de non évaluée "Set" s comme ceci:

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

Si vous appelez ReleaseHold sur ce qui précède alors les missions va réellement se passer.

Plus en attente et les parents ici:
Mathematica: Unevaluated vs Defer vs Hold vs HoldForm vs HoldAllComplete vs etc etc

+0

Vous avez frappé le clou sur la tête avec "... alors les devoirs arriveront réellement". J'ai besoin de Mathematica pour me donner une liste littérale de '{(a = 1);, (b = 2);, ...}' sans évaluer mais aussi sans les structures de Hold [] laissées dedans. – Timo

+0

OUI! Reporter [] fait l'affaire. – Timo

1

est ici une solution de rechange que je l'ai utilisé quand j'ai voulu avoir RuleDelayed applications qui ont des effets secondaires. Vous utilisez une autre tête pour remplacer Set jusqu'à ce que vous ayez votre expression sur le côté droit d'un formulaire RuleDelayed (où il sera détenu par l'attribut HoldRest de RuleDelayed), puis remplacez Set. Lorsque je fais cela , J'aime utiliser Module pour créer un symbole unique pour moi. De cette façon, vous n'avez pas besoin d'utiliser Defer, qui est une construction encore plus désagréablement glissante que Unevaluated.

Voici un exemple:

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

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

La raison pour laquelle le symbole set reçoit les mêmes attributs que Set, et la raison pour laquelle le Unevaluated est là, est de vous assurer que cela fonctionne même si quelqu'un a déjà attribué une valeur à x, y ou z.

Une autre possibilité est d'envelopper toutes vos Set expressions comme la fermeture, puis utiliser Scan pour les appeler lorsque le RuleDelayed est évalué, comme ceci:

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