Lists & Arrays
One number was a field; a few flags were bools; many things in order is a LIST — the data structure behind your card deck, your playtest rows, and the grid jam's board. This is the reference for the whole list family, AP pseudocode and C# side by side.
The vocabulary, both languages
| AP pseudocode | C# on a List | What it does |
|---|---|---|
| aList[i] | list[i] | Access index i. AP counts from 1; C# counts from 0 — the exam's favorite off-by-one |
| APPEND(aList, item) | list.Add(item) | Add at the end |
| REMOVE(aList, i) | list.RemoveAt(i) | Remove at index (or Remove(item)) |
| INSERT(aList, i, item) | list.Insert(i, item) | Squeeze into position i, shifting the rest right |
| LENGTH(aList) | list.Count | How many items |
| FOR EACH item IN aList | foreach (var item in list) | Visit every item, no index needed |
| FOR i FROM 1 TO LENGTH | for (int i = 0; i < list.Count; i++) | Visit every INDEX — use when position matters |
Array vs List — same idea, one difference that matters
An array has a fixed size set at creation
(int[] scores = new int[10];); a List
grows and shrinks on demand. Underneath, a List IS an array that
copies itself into a bigger one when full — which is why adding is
usually instant and occasionally a little slow. Choose: a hand of
changing size wants a List; a fixed 8×8 board can be either (the
grid jam uses a 2D array, 12.1b).
The exam uses "list" for both and only tests operations, never
capacity management.
The four patterns you will write forever
1. Traverse to total
AP: C#:
total ← 0 int total = 0;
FOR EACH item IN aList foreach (int item in list)
total ← total + item total += item;
2. Traverse with a filter (selection inside iteration)
AP: C#:
result ← [] var result = new List<int>();
FOR EACH item IN aList foreach (int item in list)
IF (item > threshold) if (item > threshold)
APPEND(result, item) result.Add(item);
3. Find the best (the AI score loop)
AP: C#:
best ← aList[1] int best = int.MinValue;
FOR EACH item IN aList foreach (int item in list)
IF (item > best) if (item > best)
best ← item best = item;
This is the card AI's whole personality (10.2d): score every option, keep the winner. "Best" starts at an impossible value so the first real item always replaces it.
4. Swap (the shuffle's spine)
AP: C#:
temp ← aList[i] var temp = list[i];
aList[i] ← aList[r] list[i] = list[r];
aList[r] ← temp list[r] = temp;
Fisher-Yates shuffles the whole deck from exactly this: walk from the end, pick a random earlier-or-equal index, swap. Every card gets one fair chance at every slot (10.2c).
Two bugs, one rule
Bug 1 — remove while traversing forward: deleting item i shifts every later item left, and your loop's next step skips one entirely. Fix: traverse BACKWARD (from the end to the start) so the shift happens behind you:
for (int i = list.Count - 1; i >= 0; i--)
{
if (list[i].cost > 5) list.RemoveAt(i); // safe: shifts are behind
}
Bug 2 — the bounds: the last item is at index Count − 1, not Count. Accessing list[Count] is the classic IndexOutOfRange crash. The exam version: a list of 30 students has valid indices 1–30 in AP and 0–29 in C#. Write both numbers when counting matters — you have seen this trap in every MC set (11.4a).
Lists of lists — the grid
// 2D array — the grid jam's board
int[,] grid = new int[8, 8];
grid[row, col] = 1; // ROW first — always read aloud
// list-of-lists — the AP shape
List<List<int>> grid2 = new List<List<int>>();
grid2[r][c] // same convention, row first
Rows before columns is pure convention, but the convention is
everywhere; on a square board a swap is invisible, so test on a
rectangle (12.1b).
Symmetry on a grid is one expression:
mirrorCol = W − 1 − col.
Where you meet lists this year
- 10.2a — the card kickoff — the starter's six lists, met
- 10.2c — shuffle, draw, traverse — the patterns above, shipped
- 10.2d — turn logic — the AI's find-the-best loop
- 12.1b — the grid core — 2D and bounds
- ScriptableObjects — what your lists are full of