2D Arrays Grade 11

A two-dimensional array stores data in a grid of rows and columns — like a table or spreadsheet. Each element is accessed using two indices: [row, column].

What is a 2D Array?

A two-dimensional (2D) array is a single variable that stores many values arranged in a grid of rows and columns. Where an ordinary (one-dimensional) array is like a single shopping list running down the page, a 2D array is like a whole spreadsheet — a block of cells where every value sits at the crossing point of a row and a column.

Analogy: think of a spreadsheet such as Excel. To find a cell you give a column letter and a row number — for example C5. A 2D array works exactly the same way, except we use two numbers: the first for the row and the second for the column. So myArray[2,3] means "the value in row 2, column 3", just like clicking one cell in a grid.

PURPOSE

We use 2D arrays to store tables of data that naturally have rows and columns — for example a class register of marks where each row is a learner and each column is a subject, a seating plan, a noughts-and-crosses board, or temperatures recorded for each day across several weeks. One neat variable holds the whole table instead of dozens of separate variables.

Why Do We Use 2D Arrays?

Declaration

Before you can use a 2D array you must declare it, telling Delphi how many rows and columns it has and what type of data each cell holds. You give two ranges in the square brackets: the first range is the rows and the second is the columns.

Syntax
var
  arrName : array [rowStart..rowEnd, colStart..colEnd] of DataType;
Delphi — 2x3 integer array
var
  myArray : array [1..2, 1..3] of Integer;

The example above creates a grid with 2 rows and 3 columns, giving 6 integer cells in total. Note: the ranges can start at any number, but in CAPS we almost always start at 1 so that "row 1" really is the first row.

Visualising a 2D Array

The table below shows how the index numbers map onto the grid. Read it like a spreadsheet: pick a row down the side and a column across the top, and the cell where they meet is the array element you are referring to.

Col 1Col 2Col 3
Row 1myArray[1,1]myArray[1,2]myArray[1,3]
Row 2myArray[2,1]myArray[2,2]myArray[2,3]

Populating a 2D Array

Populating means putting values into the cells. There are two common ways: assigning each cell one by one (fine for a few known values), or using nested loops to fill the whole grid quickly.

Fixed values

Here we set each cell directly by naming its row and column. This is clear but tedious — imagine doing it for a 30 × 6 register. Use it only when you have a handful of specific values to place.

Delphi
myArray[1,1] := 10;  myArray[1,2] := 20;  myArray[1,3] := 30;
myArray[2,1] := 40;  myArray[2,2] := 50;  myArray[2,3] := 60;

Nested FOR loops (most common)

This is the technique you will use most often. The outer loop moves through the rows; for each row the inner loop moves through every column. The result is that the inner loop runs completely for each turn of the outer loop, so the code visits every cell, one full row at a time — exactly like reading a spreadsheet left-to-right, then dropping down to the next line.

Delphi
var
  myArray : array [1..3, 1..4] of Integer;
  r, c    : Integer;
begin
  for r := 1 to 3 do
    for c := 1 to 4 do
      myArray[r, c] := r * c;   // e.g. row 2, col 3 = 6
end;

Displaying a 2D Array

To show the grid neatly we again use nested loops, but this time we build up one line of text per row. For each row we start with an empty string, add every column value to it (padding each so the columns line up), and only then add the finished line to the memo. Important Rule: the line is built inside the inner loop but written out in the outer loop — that is what keeps each row on its own line.

Delphi — display as table in memo
var
  sLine: string;
  r, c:  Integer;
begin
  memOut.Clear;
  for r := 1 to 3 do
  begin
    sLine := '';
    for c := 1 to 4 do
      sLine := sLine + IntToStr(myArray[r,c]).PadLeft(5);
    memOut.Lines.Add(sLine);
  end;
end;

Calculations on 2D Arrays

A big reason for using a grid is to add things up. The trick is knowing which index to fix and which to vary. If you think of the class register again: a row total is one learner's marks added across all subjects, while a column total is one subject's marks added across all learners.

Row total

To total a single row we fix the row number (here row 1) and let the column index c change. The loop walks across that one row, adding each cell to a running total. This answers "what is everything in this row added together?" — for example one learner's total mark.

Delphi — total of row 1
iTotal := 0;
for c := 1 to 4 do
  iTotal := iTotal + myArray[1, c];

Column total

Now we do the opposite: we fix the column number (here column 2) and let the row index r change. The loop runs straight down that one column, adding each cell. This answers "what is everything in this column added together?" — for example the total of all learners' marks for one subject.

Delphi — total of column 2
iTotal := 0;
for r := 1 to 3 do
  iTotal := iTotal + myArray[r, 2];

Grand total of all elements

To add up every cell in the whole grid we need nested loops again — the outer loop for rows, the inner loop for columns — so the running total picks up each cell exactly once. This is how you would work out the grand total of all marks for the entire class across all subjects.

Delphi
iTotal := 0;
for r := 1 to 3 do
  for c := 1 to 4 do
    iTotal := iTotal + myArray[r, c];