How the %SubArr built-in function works
The %SubArr built-in function is the grown-up, free-form version of the old MoveA op-code. MoveA is still a valid solution and has some limited use, but for better control, you will want to use the new %SubArr BIF. The %SubArr BIF allows you to specify the starting element and, unlike the MoveA op-code, the specific number of array elements you want to extract or set (by contrast, the MoveA op-code simply proceeds until it hits the defined/declared end of one or both of the arrays, something you absolutely cannot let happen when using dynamic arrays if you have not allocated space for all the declared elements).
The syntax for the %SubArr BIF is as follows:
%SubArr(array: start_element [: number_of_elements])
The first parameter of the %SubArr BIF is the array upon which you want to operate. The second parameter is the starting element. And the optional third parameter is the number of elements to extract or set (of course, when operating on a dynamic array, this third parameter is generally mandatory).
If you want to assign new values to (i.e., set) an array, then you specify the %SubArr BIF is on the left-hand side of an assignment operator.
%SubArr(Arr1, 1, 10) = Arr2
The above line will copy the values of the first ten elements of array Arr2 to elements 1-10 of array Arr1.
If you want to extract a portion of an array, then you will specify the %SubArr BIF on the right-hand side of an assignment operator.
Arr2 = %SubArr(Arr1, 1, 10)
The above line will copy the values of elements 1-10 of array Arr1 to the first ten elements of array Arr2.
Understanding the %SubArr built-in function
The easiest way to better understand the %SubArr built-in function is to look at a few more simple examples. Let's start with the one we saw earlier:
Eval %SubArr(Arr1: 1: 10) = Arr2 – or the totally free format version – %SubArr(Arr1: 1: 10) = Arr2;
These two lines are equivalent and will result in the first 10 elements of Arr2 being copied into the first 10 elements of Arr1. Here is another way of writing the same thing more explicitly:
%SubArr(Arr1:1:10) = %SubArr(Arr2:1:10); Now, let's vary it a bit: %SubArr(Arr1: 11: 10) = Arr2;
The code above will copy the first 10 elements of Arr2 into elements 11-20 of Arr1.
You can also omit the last parameter (i.e., the number of elements) and %SubArr will default it to the remainder of the array.
%SubArr(Arr1: 5) = Arr2;
The example above will copy array elements starting from element one of Arr2 and element five of Arr1, and will continue until the end of one of the arrays is reached. You could copy the elements back into Arr2 using:
Arr2 = %SubArr(Arr1: 5);
Sorting partial arrays
The real power of the %SubArr built-in function comes when it is combined with the SortA op-code. This combination allows you to sort just part of an array. This is especially useful when working with dynamic arrays.
Let's take the sample program from parts 2 and parts 3 and modify it slightly to get the program HEAPSORT.RPG. As before, the program first allocates enough dynamic memory for 100 elements of the dynamic array. Then the program fills those elements with some pseudo-random data. We do this by changing the definition of the array from data type timestamp to type char(2), and then using the following steps:
1. Fill the array elements with the second and third digits of the millisecond returned by the system clock (note, even though milliseconds are six digits long, the last three digits are always 000). So, if the system clock returns 345000 as the milliseconds, '45' will be put into the array element being filled at the time.
2. After each array element is filled, the program pauses briefly by looping.
In the heart of the program, after the first 100 elements of the array are allocated and filled, those elements are sorted. As mentioned, this is done by combining the SortA op-code and the %SubArr built-in function. Then, the allocated space for the dynamic array is increased to accommodate 200 elements. Next, elements 101-200 are filled in a similar fashion, and then the entire array (i.e., the allocated 200 elements) is re-sorted.
Several times along the way, a few elements of the array are displayed so you can make sure the program is working as designed.
About the author: Ron Turull is editor of Inside Version 5. He has more than 20 years' experience programming for and managing AS/400-iSeries systems.
This was first published in September 2006