Subscribe Bookmark RSS Feed

List of expressions

pcarroll1

Community Trekker

Joined:

Aug 11, 2016

I'd like to build up a list that looks like this. 

      LL = {parm1 = "x", value1 = 5, parm2 = "y", value2 = 3, ...}

The length may vary, so I'm doing it in a loop and trying to use the loop index in the variable name.

But I am having difficulty creating that term (e.g. parm1).

What is the best way to do this?

 

1 ACCEPTED SOLUTION

Accepted Solutions
pmroz

Super User

Joined:

Jun 23, 2011

Solution

Here's another way to do it.  Similar to your final solution.

//      LL = {parm1 = "x", value1 = 5, parm2 = "y", value2 = 3, ...}

// Assume parameters and value labels are sequential
parm_list  = {"x", "y", "z"};
value_list = {5, 3, 1};

pval_list = {};

for (i = 1, i <= nitems(parm_list), i++,
	one_parm = evalinsert("\[parm^i^ = "^parm_list[i]^"]\");
	one_val  = evalinsert("\[value^i^ = ^value_list[i]^]\");
	
	insertinto(pval_list, parse(one_parm));
	insertinto(pval_list, parse(one_val));
);

pval_list;
5 REPLIES
txnelson

Super User

Joined:

Jun 22, 2012

Here is a similar piece of code to generate a list

Names Default To Here( 1 );
dt = New Table( "Untitled 36", Add Rows( 3 ), 
	New Column( "Column 1", Character, "Nominal", 
	Set Values( {"1", "2", "3"} ) ) );

NamesList = {"Cool", "Awsome", "Bad"};
	
ValuesList = Column( dt, 1 ) << get values;

NamesValuesList = {};

// Build the Value Labels List
For( i = 1, i <= N Items( NamesList ), i++,
	Insert Into( namesvalueslist, 
		Parse( ValuesList[i] || " = \!"" || NamesList[i] || "\!"" ) )
);
Jim
markbailey

Staff

Joined:

Jun 23, 2011

The "best way?" Are you trying to start a fight in the JMP Community?

There is more than one way to solve this problem. The decision about which way is the best depends on several criteria. Here is another candidate solution that is different from Jim's solution but not necessarily any better.

Names Default To Here( 1 );

// List the variable names
name list = { "Cool", "Awesome", "Bad" };

// List the variable values
value list = { 1, 2, 3 };

// Prepare an empty container for assignments
name value list = {};

// Make the list of assignments
For( i = 1, i <= N Items( name list ), i++,
	// Start with function with no arguments
	assign expr = Expr( Assign() );
	// Add first argument
	Insert Into( assign expr, name list[i] );
	// Add second argument
	Insert Into( assign expr, value list[i] );
	// Add function to assignment list
	Insert Into( name value list, Name Expr( assign expr ) );
);

Show( name value list );

Now you have a choice. (I bet you have another any moment.) You choose.

 

Learn it once, use it forever!
pcarroll1

Community Trekker

Joined:

Aug 11, 2016

I will not rate which is best.  But I did find both examples useful to understand how it all works.

In the end my code looked like this.  Note: this will not run as is since I don't define some things here.

This is in a loop with index k.  A list of list stores all the results.

LList = {};

Insert Into(LList,Parse("TestParam"||char(k)||"=\!""||Modes[k]||"\!"")); // Test Param Name

Insert Into(LList,Parse("FitParam"||char(k)||"=\!""||dtStats[1,1]||"\!"")); // Fit Param Name

Insert Into(LList,Parse("Rsq"||char(k)||"="||char(dtStats[1,3]))); // Rsquared

 

vince_faller

Super User

Joined:

Mar 17, 2015

it really looks to me like you could do a list of associative arrays or nested associative arrays if you want.  Then you don't have to Parse Strings in order to create your data structure and I find it WAY easier to read (when you parse strings to create variables, you lose the ability to just run them or mouse over in order to see them. )

 

Names Default to here(1);

testparam1 = 1;
fitparam1 = 2;
Rsq1 = 3;
testparam2 = 4;
fitparam2 = 5;
Rsq2 = 6;

//list of associative arrays
Laa = {};
//param1 insert
insert into(Laa, associative array({"TestParam", "FitParam", "Rsq"}, Evallist({testparam1, fitparam1, Rsq1})) );
//param2 insert
insert into(Laa, associative array({"TestParam", "FitParam", "Rsq"}, Evallist({testparam2, fitparam2, Rsq2})) );

show(Laa[1]["TestParam"], Laa[2]["TestParam"]);

//nested associative arrays

Naa = associative array();
//param1 insert
Naa["name1"] = associative array({"TestParam", "FitParam", "Rsq"}, Evallist({testparam1, fitparam1, Rsq1}));
//param2 insert
Naa["name2"] = associative array({"TestParam", "FitParam", "Rsq"}, Evallist({testparam2, fitparam2, Rsq2}));

show(Naa["name1"]["FitParam"], Naa["name2"]["FitParam"]);

 

returns

Laa[1]["TestParam"] = 1;
Laa[2]["TestParam"] = 4;
Naa["name1"]["FitParam"] = 2;
Naa["name2"]["FitParam"] = 5;

 

the benefit of the nested really only being if you expect that order would change and position matters. 

pmroz

Super User

Joined:

Jun 23, 2011

Solution

Here's another way to do it.  Similar to your final solution.

//      LL = {parm1 = "x", value1 = 5, parm2 = "y", value2 = 3, ...}

// Assume parameters and value labels are sequential
parm_list  = {"x", "y", "z"};
value_list = {5, 3, 1};

pval_list = {};

for (i = 1, i <= nitems(parm_list), i++,
	one_parm = evalinsert("\[parm^i^ = "^parm_list[i]^"]\");
	one_val  = evalinsert("\[value^i^ = ^value_list[i]^]\");
	
	insertinto(pval_list, parse(one_parm));
	insertinto(pval_list, parse(one_val));
);

pval_list;