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 valuesAnalogously, across two arrays it works to some extent:
For Each( {a, i}, Across( q, w ), show( i, a ) );<BR />// 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 ) );<BR />// 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 ) );<BR />// returns error:<BR />argument value is invalid in access or evaluation of 'For Each' , Bad Argument( {a, b} ), For Each/*###*/({{{a, b}, <BR />{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?
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.
https://www.jmp.com/support/help/en/17.2/#page/jmp/conditional-and-logical-functions.shtml?os=win&source=application#ww10169967
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));