[Closed] Collect nested for loops to a single flat array?
Is there a simple way to do this?
For example, the following line:
for i = 1 to 5 collect (for j = 1 to 3 collect (i * j))
returns a multidimensional array of #(#(1, 2, 3), #(2, 4, 6), #(3, 6, 9), #(4, 8, 12), #(5, 10, 15))
But what I want is just a one dimensional array of all the collected values in sequence, i.e. #(1, 2, 3, 2, 4, 6, 3, 6, 9, 4, 8, 12, 5, 10, 15)
Up until now I’ve just been using the format of
(
testArray = #(); for i = 1 to 5 do (for j = 1 to 3 do append testArray (i * j))
testArray
)
which seems to be a cumbersome way to get the results I’m looking for. So, is there a better way to do this?
To expand on what Denis said, there IS another variation of what you did there, but it turned out to be over 3 times slower, probably due to the different memory management / garbage collection behavior.
Your expression grows the array one item at a time via append.
The following builds an array in the inner loop, then joins it to the big flat array, thus growing two arrays in large chunks. With 1000×1000 iterations, your expression takes about a second, while the following takes about 3.5 (on my 2 core laptop):
testArray = #(); for i = 1 to 1000 do join testArray (for j = 1 to 1000 collect (i * j))
Also, it does not look any more elegant than your solution.
So stick to the fastest method
you can force max to do just one allocation
a = #();
a.count = 5 * 3;
i = 1;
for j = 1 to 5 do for k = 1 to 3 do ( a[i] = (k * j); i += 1; )
a
might win out if the numbers get big
Actually I tested this as part of the other two test runs and it was about half way between the two time-wise (about 2 seconds for 1000×1000 iterations on my laptop).
Even without the index counter, it is not faster than the append() method – I got it down to about 1.8 seconds per million iterations.
(
a = #()
a.count = 5 * 3
for j = 1 to 5 do for k = 1 to 3 do ( a[(j-1)*3+k] = (k * j) )
a
)
Since these look even less stylish (smell a lot like MEL to me ), I decided to omit them.
Thanks for mentioning that option!