When it was introduced in IBM i 7.4 I thought the Split built in function, BiF, would be useful way to break apart a string into pieces. The one frustration I had with it was when two separators were next to one another %SPLIT would not regard it as an empty, or null, sub-string.
Let me jump straight into my RPG program to demonstrate how this works. Let me start with all the definitions, etc.
01 **free 02 dcl-s String varchar(100) inz('RED,,BLUE,,GREEN,,,BLACK') ; 03 dcl-s Piece char(10) ; 04 dcl-s Array char(10) dim(*auto:999) ; |
Line 1: In 2023 all of our new RPG should be totally free format RPG.
Line 2: This is the definition for the variable that contains the string I want to split into its parts, I'm calling them sub-strings.
Line 4: An array I will be using later in this program.
This next snippet shows how the %SPLIT BiF works:
05 for-each Piece in %split(String : ',') ; 06 dsply ('1: ' + Piece) ; 07 endfor ; |
Line 5: The %SPLIT returns its results like an array, therefore, I can use the FOR-EACH operation code to read, one at a time, all of its elements.
Line 6: I display the information that the FOR-EACH has placed in the RPG variable Piece.
As %SPLIT handles repeating separator characters as one, the displayed results are:
DSPLY 1: RED DSPLY 1: BLUE DSPLY 1: GREEN DSPLY 1: BLACK |
A new parameter was added to %SPLIT in IBM i 7.5 TR2 and IBM i 7.4 TR8. This parameter is the keyword *ALLSEP. This "tells" the BiF to treat multiple separators next to one another as a blank sub-string. All I need to change is the FOR-EACH line:
08 for-each Piece in %split(String : ',' : *ALLSEP) ; 09 dsply ('2: ' + Piece) ; 10 endfor ; |
Line 8: I have entered the *ALLSEP in upper just to make it easy to see. It works equally well in lower or mixed case.
The results now look like:
DSPLY 2: RED DSPLY 2: DSPLY 2: BLUE DSPLY 2: DSPLY 2: GREEN DSPLY 2: DSPLY 2: DSPLY 2: BLACK |
As there are two commas between 'RED' and 'BLUE', and between 'BLUE' and 'GREEN' there are blank sub-strings returned as the second and fourth results.
There are three commas between 'GREEN' and 'BLACK', thus, there are two blank results returned.
As the results from %SPLIT are returned like an array I can "load" an array from the results of the split.
11 Array = %split(String : ',' : *ALLSEP) ; 12 dsply ('Elements = ' + %char(%elem(Array))) ; |
Line 11: I defined, on line 4, that the array Array as an auto-extending array, this allows me to dump the results of the %SPLIT directly into the array without the need to increment the elements for each returned sub-string. The result is an array that contains only the number of elements as there are sub-strings in the string.
Line 12: I want to display the number of array elements.
I put a debug break at line 12, and when I display the values of Array I can see the sub-strings loaded into the array.
EVAL array ARRAY(1) = 'RED ' ARRAY(2) = ' ' ARRAY(3) = 'BLUE ' ARRAY(4) = ' ' ARRAY(5) = 'GREEN ' ARRAY(6) = ' ' ARRAY(7) = ' ' ARRAY(8) = 'BLACK ' |
When line 12 is executed it shows that the array only contains eight elements, one for each of the sub-strings.
DSPLY Elements = 8 |
A great addition to the %SPLIT BiF, making it more useful than it was before.
You can learn more about the %SPLIT bilt in function from the IBM website here.
This article was written for IBM i 7.5 TR2 and 7.4 TR8.
Ah, so RPG finally has an 'unstring' function. Nice. Now I'm only waiting for a 'continue' ;-)
ReplyDeleteThe strtok function has been available since ile-rpg has been available.
ReplyDelete