cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Try the Materials Informatics Toolkit, which is designed to easily handle SMILES data. This and other helpful add-ins are available in the JMP® Marketplace
Choose Language Hide Translation Bar
AlterEgo
Level II

For Each Loop across multiple associative arrays

Hi,

 

I'm struggling with the syntax for a For Each loop across multiple associative arrays.

 

For example:

q = ["q1"=>11, "q2"=>22, "q3"=>33];
w = ["w1"=>1111, "w2"=>2222, "w3"=>3333];

For single array, just for reference:

For Each( {a, i}, q, Show( i, a ) ); // retrieves indices and keys
For Each( { {a, b}, i }, q, Show( i, a, b ) ); // retrieves indices, keys and values

Analogously, across two arrays it works to some extent:

For Each( {a, i}, Across( q, w ), show( i, a ) );
// retrieves indices and two-item lists of keys of both arrays: i = 1; a = {"q1", "w1"}; i = 2; a = {"q2", "w2"}; i = 3; a = {"q3", "w3"};

Then drilling further:

For Each( { {a, b}, i }, Across( q, w ), show( i, a, b ) );
// retrieves indices and keys of both arrays separately: i = 1; a = "q1"; b = "w1"; i = 2; a = "q2"; b = "w2"; i = 3; a = "q3"; b = "w3";

However, I want to get values also. I tried several variants of brace groupings and nothing works. Drawing from the single array syntax this should be the most obvious one:

For Each( { { {a, b}, {c, d} }, i }, Across( q, w ), show( i, a, b, c, d ) );
// returns error:
argument value is invalid in access or evaluation of 'For Each' , Bad Argument( {a, b} ), For Each/*###*/({{{a, b},
{c, d}}, i}, Across( q, w ), Show( i, a, b, c, d ))

I RTFM-ed and RTFF-ed and couldn't find anything.

 

Of course I can do this:

For Each( { {a, b}, i }, Across( q, w ), show( i, a, b, q[a], w[b] ) );

but this is not the point. It's a matter of elegance. 

 

Any ideas?

2 REPLIES 2
jthi
Super User

Re: For Each Loop across multiple associative arrays

https://www.jmp.com/support/help/en/17.2/#page/jmp/conditional-and-logical-functions.shtml?os=win&so...

When specifying multiple containers using the Across() keyword, the names list contains a list of names that refer to values in each container. The number of names in the first item in the names list must match the number of containers specified in the Across() keyword.

 

And for associative array

For an associative array container, the names list contains a two-item list of names and a name for the index of each item in the associative array.

 

So I think you have to go with something like you did suggest

Names Default To Here(1);

aa1 = ["q1" => 11, "q2" => 22, "q3" => 33];
aa2 = ["w1" => 1111, "w2" => 2222, "w3" => 3333];

For Each({{key1, key2}, i}, Across(aa1, aa2),
	val1 = aa1[key1];
	val2 = aa2[key2];
	Print(Eval Insert("\!Ni = ^i^"));
	Print(Eval Insert("key1 = ^key1^, val1 = ^val1^"));
	Print(Eval Insert("key2 = ^key2^, val2 = ^val2^"));
);

or maybe something like this (which also feels a bit weird)

Names Default To Here(1);

aa1 = ["q1" => 11, "q2" => 22, "q3" => 33];
aa2 = ["w1" => 1111, "w2" => 2222, "w3" => 3333];

For Each({{key1, key2, val1, val2}, i}, Across(aa1, aa2, aa1 << get values, aa2 << get values),
	Print(Eval Insert("\!Ni = ^i^"));
	Print(Eval Insert("key1 = ^key1^, val1 = ^val1^"));
	Print(Eval Insert("key2 = ^key2^, val2 = ^val2^"));
);

There might be some syntax which should be used, but I have no idea what it could be and I agree something like this would most likely be the most obvious one

For Each({{{key1, val1}, {key2, val2}}, i}, Across(aa1, aa2), Show(i, key1, val1, key2, val2));
-Jarmo
AlterEgo
Level II

Re: For Each Loop across multiple associative arrays

Thanks for the reply. As mentioned, it's not that I cannot easily extract the values. I just find it weird that for a single associative array it's also possible to reference the values using a nested list, but not across multiple arrays.