Sets and arrays

After defining a type, we will use it in our code, either as a standalone variable or as a collection. The most basic collection type is a set. It is very powerful and not available in other programming languages. We could, for example, define a set of qualifying school grades. The elements of a set are enclosed in square brackets. Refer to the following code:

type 
  TSchoolGrade = (sgVeryGood, sgGood, sgSufficient, sgInsufficient); 
  TSchoolGrades = set of TSchoolGrade; 
 
const 
  QUALIFYING_GRADES: TSchoolGrades = [sgVeryGood, sgGood, sgSufficient]; 
 
function IsQualifyingGrade(sg: TSchoolGrade): boolean; 
begin 
  Result := sg in QUALIFYING_GRADES; 
end; 

Using the in operator, we can check if a given value belongs to a set. It is also possible to use other operators to combine sets, calculate their intersections, and, in general, implement other set theory operations.

Another built-in type for dealing with collections of values is an array. Arrays can have either a fixed or a varying size. If it is fixed, then we need to define upfront how many elements an array can hold. It is also possible to use dynamic arrays. In this case, we can change the size of an array in code using the SetLength procedure and check its current size with the Length function. Once we are done with using a dynamic array, it is a good idea to pass it to the Finalize procedure, so the memory it occupies can be properly freed.

One interesting usage scenario for fixed arrays is defining a record constant array. Such an array needs to have a fixed size because it is embedded in the program during the compile time. This way, you can avoid writing code for initializing an array and adding elements to it.

Let's consider chess. Chess pieces do not change, and sometimes, it makes sense to assign a relative value to them, so a simple chess program can make decisions if it makes sense to exchange pieces. Why not to hardcode this information?

type 
  TChessPiece = record 
    Name: string; 
    Value: Double; 
  end; 
 
const 
  CHESS_PIECES_COUNT = 6; 
 
  CHESS_PIECES: array[0..CHESS_PIECES_COUNT-1] of TChessPiece = 
    ( 
      (Name : 'Pawn'; Value : 1), 
      (Name : 'Knight'; Value : 3), 
      (Name : 'Bishop'; Value : 3), 
      (Name : 'Rook'; Value : 5), 
      (Name : 'Queen'; Value : 9), 
      (Name : 'King'; Value : 0) 
    ) ; 

Obviously, this is only an example, and chess piece valuations can be different depending on the phase in the game and expert opinions.

Instead of using an array of a fixed size, it is more common to use dynamic arrays. We can initialize them as if they were of a fixed size and perform set operations on them, as shown in the following code snippet:

var fruits: array of string; 
begin 
  fruits := ['Apple', 'Pear']; 
  fruits := fruits + ['Banana', 'Orange']; 
// ... 

Dynamic arrays also allow using the Insert and Delete procedures for adding and removing a specified number of elements from a given position in an array.