Wednesday, June 14, 2023

RPG %SPLIT now handles blank sub-strings

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.

2 comments:

  1. Ah, so RPG finally has an 'unstring' function. Nice. Now I'm only waiting for a 'continue' ;-)

    ReplyDelete
  2. The strtok function has been available since ile-rpg has been available.

    ReplyDelete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.