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.

How do I generate a list of strings from a list of assigned variables?

Eg. Convert

var1 = 10;
var2 = 11;
var3 = 17;
var4 = 5;

compvar = {var1, var2, var3, var4}; (*all variables assigned*)

into,

compvarstr = {"var1", "var2", "var3", "var4"};

Using ToString obviously converts the variables assignments into strings e.g.

compvarstr = ToString[#] & /@ compvar

gives,

{"10", "11", "17", "5"}

i'm after the unassigned variable names as strings e.g.

{"var1", "var2", "var3", "var4"};

Apologies if this is a duplicate - I had a bit of a look and nothing seemed to answer it.

share|improve this question
    
you mean this? compvarstr = ToString[#] & /@ compvar !Mathematica graphics –  Nasser Jan 18 at 2:42
    
@Nasser - please review my edit. I hope the question is clearer now. –  geordie Jan 18 at 2:51
    
I see now after your edits. But what you are asking for can't be done as is. Once you make an assignment, compvar becomes {10, 11, 17, 5}, becuase M has evaluated all those variables to their values. Only way, is not to make the assignment to the valuates, but using replacement rule. I'll post an example –  Nasser Jan 18 at 2:53

3 Answers 3

up vote 2 down vote accepted

Edit: I accidentally copied the wrong function name in my original post.
If you tried my code unsuccessfully please try again now.


You must introduce some form of holding in you definition of compvar as otherwise, assuming it is defined after var1, var2, etc., there is no information to retrieve:

var1 = 10;
var2 = 11;
var3 = 17;
var4 = 5;

compvar = {var1, var2, var3, var4};

Definition[compvar]
compvar = {10, 11, 17, 5}

You could use Hold but then you would need to ReleaseHold (or similar) every time you used compvar. Instead I suggest you use SetDelayed and then recover the definition using my step function from:

It returns an expression wrapped in HoldForm:

compvar := {var1, var2, var3, var4};

step[compvar] // InputForm
HoldForm[{var1, var2, var3, var4}]

To convert to a list of strings:

Cases[step[compvar], s_Symbol :> SymbolName @ Unevaluated @ s, {2}]
{"var1", "var2", "var3", "var4"}

Or:

StringSplit[ToString @ step[compvar], ("{" | "," | " " | "}") ..]
{"var1", "var2", "var3", "var4"}

The first method will return Symbols (as strings) only while the second will convert other expressions as well.

share|improve this answer
    
Nice explanation - Thanks. –  geordie 2 days ago
    
@geordie You're welcome, and thanks for the Accept. –  Mr.Wizard 2 days ago

Here's a way:

var1 = 10;
var2 = 11;
var3 = 17;
var4 = 5;
compvar := {var1, var2, var3, var4}
compvar; (*all variables assigned*)

ClearAll[f];
SetAttributes[f, {HoldAll}];
f[x_, y__] := Flatten@{f[x], f[y]}
f[x_] := SymbolName@Unevaluated@x

OwnValues[compvar] /. {HoldPattern[y_] :> {x__}} :> f[x]

(*
 {"var1", "var2", "var3", "var4"}
*)
share|improve this answer

one way is to make a replacement rule seperately and use that.

Clear[var1, var2, var3, var4];
vars = {var1, var2, var3, var4};
values = {var1 -> 10, var2 -> 11, var3 -> 17, var4 -> 5};
compvar = vars /. values

Mathematica graphics

compvarstr = ToString[#] & /@ vars
FullForm[compvarstr]

Mathematica graphics

Otherwise, the way you had it:

 var1 = 10; var2 = 11; var3 = 17; var4 = 5;
 compvar = {var1, var2, var3, var4}; (*all variables assigned*)

Now the var1 name itself is replaced by 10 right away by the evaluator. Hence compvar will always be {10, 11, 17, 5} and the name of the variables is not known inside compvar since their value is used.

share|improve this answer
    
This wont work for my case (setting up the rules each time will be a fiddle) but it has made me realise that going the other way is easy e.g. compvar = ToExpression[compvarstr]. Many thanks! –  geordie Jan 18 at 3:10
    
@geordie if that works for you then good. But I think writing values = {var1 -> 10, var2 -> 11, var3 -> 17, var4 -> 5}; is not more a problem than writing var1 = 10; var2 = 11; var3 = 17; var4 = 5; and using replacement rule is more flexible in many other ways and for many other uses as well. But again, whatever works for you ;) –  Nasser Jan 18 at 3:13
    
Agreed, however, in my full code "var1" through "var4" are nested lists and have names like "vh88exp1", "vh88sswl", "bpqm10", etc... So it is quite easy for me to write out their names as a list of strings. Thanks again. –  geordie Jan 18 at 3:24

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.