Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

As part of a calculation I need to do something like this

Evaluate[{aaa, bbb, ccc}[[ index]]] = {1, 2, 3, 4, 5}

so if index is 1 then {1, 2, 3, 4, 5} will be stored into the variable aaa.
But if I re-evaluate this it does not work because aaa is now a list and not a variable. I tried various options with Hold[] etc but did not manage to solve this.

share|improve this question

migrated from stackoverflow.com Jun 6 '12 at 23:46

This question came from our site for professional and enthusiast programmers.

    
Related: (1), (2), (3), (4), (5) –  Mr.Wizard Jun 6 '12 at 23:49
    
All: please comment if you believe this question or any of the "Related" ones should be merged. –  Mr.Wizard Jun 6 '12 at 23:54
    
BlueMac, I notice that you never Accepted an answer to this question. Is there anything that remains unanswered, or something I can do to make my answer more satisfying? –  Mr.Wizard Jul 6 at 22:10

3 Answers 3

This is a fairly natural question and I feel it is worthy of attention. I am going to answer in two parts. First, I am going to show a method that is more appropriate for Mathematica programming and which I recommend you use instead. Then I will show how to force the action you are attempting.


A Better Alternative

The normal way to accomplish programmatically selected assignments is to use indexed variables. This allows you to assemble a "variable" from inert parts. For example, one would use a single variable var and simply make assignments (SeedRandom[1] for a consistent result):

SeedRandom[1]

Do[
  var[i] = RandomInteger[9],
  {i, {1, 2, 3, 2, 3, 1, 3}}
]

Or recall them:

var /@ {1, 2, 3}
{0, 7, 8}

If you desire a certain name be attached to a value you can index with Strings.

names = {"aaa", "bbb", "ccc"};

i = 1;

var[ names[[i]] ] = Sqrt[2]; (* dummy first assignment *)

var[ names[[i]] ] = {1, 2, 3, 4, 5};

var["aaa"]
{1, 2, 3, 4, 5}

In passing, depending on your application you may find Rules applicable.


Forcing the behavior

Suppose you need the behavior you asked for to keep a large program working without extensive modification.

Method #1

This works because Part preserves the head of the expression, here Unevaluated.

Ignore the syntax highlighting in Unevaluated: this is a nonstandard but safe use.

This could easily use the same syntax as Method #2: assign[symbols_, idx_, val_] :=

ClearAll[aaa, bbb, ccc, assign]
assign[idx_, val_] := (# = val) & @ symbols[[1, {idx}]]

symbols = Hold @ Unevaluated[aaa, bbb, ccc];

assign[1, "dummy"];
assign[1, Range@5];

aaa
{1, 2, 3, 4, 5}

Method #2

This uses the injector pattern in preference to Unevaluated.

ClearAll[aaa, bbb, ccc, f1, assign]
assign[symbols_, idx_, val_] := symbols[[{idx}]] /. _[x_] :> (x = val)

symbols = Hold[aaa, bbb, ccc];

assign[symbols, 1, "dummy"];
assign[symbols, 1, Range@5];

aaa
{1, 2, 3, 4, 5}
share|improve this answer

I would not recommend it, but you could do something like

varlist = "var1,var2,var3";
index   = 2;
ToExpression[StringSplit[varlist, ","][[index]] ~~ "={1, 2, 3, 4, 5}"];
var2
(* -> {1, 2, 3, 4, 5} *)
share|improve this answer

Keep data out of your variable names

Use functional programming where, whenever you use aaa, it is an argument to a function. If you want to pass something different in, call the function.

If you really want to do this, use one of the HoldAll-like attributes here.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.