RPGLE Array and List BIFs Reference

This page is a lookup for the RPGLE built-in functions that work on arrays. It shows what each one takes, what it returns, and the edge cases that give a zero or a run-time error.

For how arrays are declared, loaded and sorted, read RPGLE Arrays and Tables. The complete list of BIFs is in the RPGLE Built-in Functions Reference.

All examples are free-form RPGLE. Array indexes start at 1.

Array BIFs at a glance

BIFWhat it doesReturns
%elemNumber of elements in an array, table or multiple-occurrence data structureUnsigned integer
%sizeSize in bytes of a field, or of one array element, or of the whole arrayUnsigned integer
%lookupIndex of the first element that equals a valueUnsigned integer; 0 when not found
%lookuplt, %lookuple, %lookupgt, %lookupge, %lookupneIndex of an element by comparison with a valueUnsigned integer; 0 when no element matches
%subarrA section of an array, starting at an indexAn array section

%ELEM

Returns the number of elements.

%elem(array)

The value is the declared number of elements, so it is the right bound for a loop. It can be used where a numeric constant is allowed in a declaration.

dcl-s nums int(10) dim(5);
dcl-s i int(10);

for i = 1 to %elem(nums);
  nums(i) = i * 10;
endfor;

For a varying-dimension array, declared with dim(*auto) or dim(*var), %elem also takes *alloc or *max as a second parameter, and it can be assigned to change the current number of elements.

%SIZE

Returns the number of bytes occupied by a variable or constant.

%size(variable)
%size(array {: *all})

For an array, %size returns the size of one element. With *all it returns the storage taken by every element.

dcl-s codes char(1) dim(7);

// %size(codes)         is 1
// %size(codes : *all)  is 7

For a varying-length field, %size includes the two or four bytes that hold the current length, so it is larger than the declared maximum length.

%LOOKUP

Searches an array and returns the index of the matching element, or 0 when none matches.

%lookup(arg : array {: start_index {: number_of_elements}})
ParameterMeaning
argThe value to find
arrayThe array to search
start_indexThe first index to search. Defaults to 1
number_of_elementsHow many elements to search. Defaults to the rest of the array

%lookup finds an exact match. If several elements match, it returns the index of the first one.

dcl-s letters char(1) dim(7) ascend;
dcl-s idx int(10);

letters(1) = 'A';  letters(2) = 'C';  letters(3) = 'C';  letters(4) = 'C';
letters(5) = 'E';  letters(6) = 'E';  letters(7) = 'G';

idx = %lookup('C' : letters);          // 2, the first match
idx = %lookup('C' : letters : 3);      // 3, searching from index 3
idx = %lookup('Z' : letters);          // 0, not found

%LOOKUP comparison variants

The variants search by comparison. They return the index of the element that is closest to arg in the stated direction, or 0 when there is none.

BIFFindsFor arg = 'D' in the array above
%lookupltThe last element less than arg4
%lookupleAn exact match, or the last element less than arg4
%lookupgtThe first element greater than arg5
%lookupgeAn exact match, or the first element greater than arg5
%lookupneThe first element that does not equal arg1 for 'D'; 2 for 'A'

The words “first” and “last” above are for an array declared ascend. For a descending array the direction reverses, so read the IBM i reference for your array’s order before you rely on the result. Declare the order with ascend or descend on the array so the comparison is made in that order.

idx = %lookupge('D' : letters);        // 5, the first element greater than 'D'
idx = %lookuplt('D' : letters);        // 4, the last element less than 'D'
idx = %lookupne('A' : letters);        // 2, the first element that is not 'A'

%SUBARR

Returns a section of an array. It can be used where an unindexed array is allowed, such as an assignment target or a parameter of %xfoot.

%subarr(array : start_index {: number_of_elements})

start_index must be at least 1 and no greater than the number of elements. If you leave out number_of_elements, the section runs to the end of the array. When you give it, it must be at least 1 and no greater than the number of elements remaining after the start.

dcl-s total int(10);

// nums holds 10, 20, 30, 40, 50
total = %xfoot(%subarr(nums : 2 : 3));     // 20 + 30 + 40 = 90

Choosing a lookup BIF

  • Use %lookup when you need an exact match, for example to check that a code is on a list of valid codes.
  • Use %lookupge or %lookupgt when the array holds thresholds and you want the first entry at or above a value, for example a rate band.
  • Use %lookuple or %lookuplt when you want the last entry at or below a value.
  • Use %lookupne to find the first element that differs from a value, for example the first non-blank entry in an array of blanks.
  • Pass start_index and number_of_elements to search only part of an array, such as the elements loaded so far, so that unused elements do not match.
dcl-s used int(10) inz(3);
dcl-s idx2 int(10);

// search only the first 'used' elements of the array
idx2 = %lookup('E' : letters : 1 : used);       // 0, because 'E' is not in elements 1 to 3

Searching only the loaded part of an array

An array always has its declared number of elements, even when you have loaded fewer. Elements that were never assigned hold their initial values, such as blanks or zeros, and a search can match them. Keep a counter of the elements in use and give it to %lookup as the number_of_elements parameter. That limits the search to real data, and it is cheaper than searching the whole array.

Legacy opcodes

Fixed-format code used opcodes for the same jobs. They still compile; use the BIF in new code.

Fixed-format opcodeFree-form equivalent
LOOKUP with the EQ indicator%lookup
LOOKUP with LT, LE, GT or GE%lookuplt, %lookuple, %lookupgt, %lookupge
XFOOT%xfoot

Common mistakes

  • Using the result of %lookup without testing for 0.
  • Hard-coding the declared size in a loop instead of using %elem.
  • Reading %size of an array as its total storage. Without *all it is the size of one element.
  • Expecting %lookupge or %lookuplt to work correctly on an array that is not in the order declared by ascend or descend.
  • Passing a start index or element count that runs past the end of the array to %subarr.

FAQ

How do I find an element in an RPGLE array?

Use %lookup(value : array). It returns the index of the first match, or 0 when the value is not in the array.

How do I get the number of elements in an array?

Use %elem(array). It is the declared number of elements, or the current number for a varying-dimension array.

What is the difference between %ELEM and %SIZE?

%elem counts elements. %size counts bytes: one element, or with *all the whole array.

Summary

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top