{"id":2665,"date":"2026-02-05T09:39:45","date_gmt":"2026-02-05T09:39:45","guid":{"rendered":"https:\/\/demo.materiamedica.net\/demo6\/?p=2665"},"modified":"2026-02-05T09:39:45","modified_gmt":"2026-02-05T09:39:45","slug":"chapter-40-swift-arrays-multidimensional","status":"publish","type":"post","link":"https:\/\/demo.materiamedica.net\/demo6\/chapter-40-swift-arrays-multidimensional\/","title":{"rendered":"Chapter 40: Swift Arrays: Multidimensional"},"content":{"rendered":"<h3 dir=\"auto\">1. What is a Multidimensional Array?<\/h3>\n<p dir=\"auto\">A <strong>multidimensional array<\/strong> is simply an <strong>array of arrays<\/strong>.<\/p>\n<p dir=\"auto\">In other words:<\/p>\n<ul dir=\"auto\">\n<li>You have an outer array<\/li>\n<li>Each element of the outer array is <strong>itself an array<\/strong><\/li>\n<li>So you access elements using <strong>two (or more) indices<\/strong><\/li>\n<\/ul>\n<p dir=\"auto\">Real-life analogies:<\/p>\n<ul dir=\"auto\">\n<li><strong>2D array<\/strong> \u2192 chessboard (8 rows \u00d7 8 columns)<\/li>\n<li><strong>2D array<\/strong> \u2192 monthly calendar (weeks as rows, days as columns)<\/li>\n<li><strong>2D array<\/strong> \u2192 spreadsheet table (rows and columns)<\/li>\n<li><strong>3D array<\/strong> \u2192 stack of chessboards, or RGB image (height \u00d7 width \u00d7 color channels)<\/li>\n<\/ul>\n<p dir=\"auto\">In Swift we usually talk about <strong>2D arrays<\/strong> (most common), sometimes <strong>3D<\/strong>, and rarely more.<\/p>\n<h3 dir=\"auto\">2. Creating a 2D Array \u2014 all common ways<\/h3>\n<h4 dir=\"auto\">Way 1 \u2013 Literal syntax (most readable for small fixed data)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let matrix = [\r\n    [1, 2, 3],\r\n    [4, 5, 6],\r\n    [7, 8, 9]\r\n]\r\n\r\n\/\/ Access: row 1 (second row), column 2 (third number)\r\nprint(matrix[1][2])     \/\/ 6<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Way 2 \u2013 Empty 2D array with fixed rows &amp; columns<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let rows = 4\r\nlet columns = 5\r\n\r\nvar grid = Array(repeating: Array(repeating: 0, count: columns), count: rows)\r\n\r\n\/\/ Now grid is:\r\n\/\/ [ [0,0,0,0,0],\r\n\/\/   [0,0,0,0,0],\r\n\/\/   [0,0,0,0,0],\r\n\/\/   [0,0,0,0,0] ]<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Way 3 \u2013 From existing data (very common)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let sales2024 = [\r\n    [\"Jan\", \"Feb\", \"Mar\", \"Apr\"],\r\n    [12000, 15000, 18000, 14000],\r\n    [13000, 16000, 19000, 14500]\r\n]<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">3. Reading from a 2D Array<\/h3>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let chessBoard = [\r\n    [\"\u265c\", \"\u265e\", \"\u265d\", \"\u265b\", \"\u265a\", \"\u265d\", \"\u265e\", \"\u265c\"],\r\n    [\"\u265f\", \"\u265f\", \"\u265f\", \"\u265f\", \"\u265f\", \"\u265f\", \"\u265f\", \"\u265f\"],\r\n    [\" \", \" \", \" \", \" \", \" \", \" \", \" \", \" \"],\r\n    [\" \", \" \", \" \", \" \", \" \", \" \", \" \", \" \"],\r\n    [\" \", \" \", \" \", \" \", \" \", \" \", \" \", \" \"],\r\n    [\" \", \" \", \" \", \" \", \" \", \" \", \" \", \" \"],\r\n    [\"\u2659\", \"\u2659\", \"\u2659\", \"\u2659\", \"\u2659\", \"\u2659\", \"\u2659\", \"\u2659\"],\r\n    [\"\u2656\", \"\u2658\", \"\u2657\", \"\u2655\", \"\u2654\", \"\u2657\", \"\u2658\", \"\u2656\"]\r\n]\r\n\r\n\/\/ Piece at row 0, column 4 (black king)\r\nprint(chessBoard[0][4])     \/\/ \u265a\r\n\r\n\/\/ White pawn at row 6, column 3\r\nprint(chessBoard[6][3])     \/\/ \u2659<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Safe access (very important)<\/strong><\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>func safeGet&lt;T&gt;(array: [[T]], row: Int, col: Int) -&gt; T? {\r\n    guard row &gt;= 0, row &lt; array.count,\r\n          col &gt;= 0, col &lt; array[row].count else {\r\n        return nil\r\n    }\r\n    return array[row][col]\r\n}\r\n\r\nprint(safeGet(array: chessBoard, row: 0, col: 4) ?? \"Empty\")    \/\/ \u265a\r\nprint(safeGet(array: chessBoard, row: 10, col: 5) ?? \"Empty\")   \/\/ Empty<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">4. Modifying a 2D Array (only if var)<\/h3>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>var scores = [\r\n    [85, 92, 78],\r\n    [88, 95, 90],\r\n    [76, 82, 87]\r\n]\r\n\r\n\/\/ Change value\r\nscores[1][2] = 99           \/\/ second row, third column \u2192 90 \u2192 99\r\n\r\n\/\/ Add new row\r\nscores.append([80, 85, 88])\r\n\r\n\/\/ Add new column to every row (careful!)\r\nfor i in 0..&lt;scores.count {\r\n    scores[i].append(0)     \/\/ add 0 as default\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">5. Looping over 2D Arrays \u2014 most common patterns<\/h3>\n<h4 dir=\"auto\">Pattern 1 \u2013 Nested for-in (classic &amp; clear)<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let matrix = [\r\n    [1, 2, 3],\r\n    [4, 5, 6],\r\n    [7, 8, 9]\r\n]\r\n\r\nprint(\"Matrix:\")\r\nfor row in matrix {\r\n    for number in row {\r\n        print(number, terminator: \" \")\r\n    }\r\n    print()     \/\/ new line after each row\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p dir=\"auto\"><strong>Output:<\/strong><\/p>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>text<\/div>\n<div>\n<pre tabindex=\"0\"><code>1 2 3 \r\n4 5 6 \r\n7 8 9<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Pattern 2 \u2013 With row &amp; column indices<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>for (rowIndex, row) in matrix.enumerated() {\r\n    for (colIndex, value) in row.enumerated() {\r\n        print(\"Position [\\(rowIndex),\\(colIndex)] = \\(value)\")\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Pattern 3 \u2013 Using indices<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>for rowIndex in matrix.indices {\r\n    for colIndex in matrix[rowIndex].indices {\r\n        print(matrix[rowIndex][colIndex], terminator: \" \")\r\n    }\r\n    print()\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">6. Real-Life Examples You Will Actually Write<\/h3>\n<h4 dir=\"auto\">Example 1 \u2013 Monthly sales table<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>let months = [\"Jan\", \"Feb\", \"Mar\", \"Apr\"]\r\nlet products = [\"Phone\", \"Laptop\", \"Tablet\"]\r\n\r\nlet sales: [[Int]] = [\r\n    [120, 150, 180],     \/\/ Phone sales per month\r\n    [45,  60,  55],      \/\/ Laptop\r\n    [80,  95,  110]      \/\/ Tablet\r\n]\r\n\r\nprint(\"Monthly Sales (\u20b9000s)\")\r\nprint(\"     \" + months.joined(separator: \"  \"))\r\n\r\nfor (productIndex, productSales) in sales.enumerated() {\r\n    let row = \"\\(products[productIndex]) \" + productSales.map { String(format: \"%4d\", $0) }.joined(separator: \" \")\r\n    print(row)\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h4 dir=\"auto\">Example 2 \u2013 Tic-tac-toe board<\/h4>\n<div dir=\"auto\">\n<div data-testid=\"code-block\">\n<div>\n<div>Swift<\/div>\n<div>\n<pre tabindex=\"0\"><code>var board = [\r\n    [\" \", \" \", \" \"],\r\n    [\" \", \" \", \" \"],\r\n    [\" \", \" \", \" \"]\r\n]\r\n\r\n\/\/ Place X in center\r\nboard[1][1] = \"X\"\r\n\r\n\/\/ Place O in corner\r\nboard[0][0] = \"O\"\r\n\r\n\/\/ Print board\r\nfor row in board {\r\n    print(row.joined(separator: \" | \"))\r\n    print(\"---------\")\r\n}<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">7. Very Common Beginner Mistakes &amp; Correct Habits<\/h3>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"xl\">Mistake<\/th>\n<th data-col-size=\"md\">Wrong \/ Dangerous code<\/th>\n<th data-col-size=\"lg\">Correct \/ Safe habit<\/th>\n<th data-col-size=\"md\">Why?<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"xl\">Forgetting outer array can be empty<\/td>\n<td data-col-size=\"md\">matrix[0][0] without check<\/td>\n<td data-col-size=\"lg\">guard !matrix.isEmpty else { \u2026 }<\/td>\n<td data-col-size=\"md\">Crash if no rows<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"xl\">Assuming all rows have same length<\/td>\n<td data-col-size=\"md\">matrix[row][col] without check<\/td>\n<td data-col-size=\"lg\">if col &lt; matrix[row].count { \u2026 }<\/td>\n<td data-col-size=\"md\">Rows can have different lengths<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"xl\">Force-unwrapping first\/last of inner array<\/td>\n<td data-col-size=\"md\">matrix[0].first!<\/td>\n<td data-col-size=\"lg\">matrix[0].first ?? default<\/td>\n<td data-col-size=\"md\">Inner array can be empty<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"xl\">Modifying let array<\/td>\n<td data-col-size=\"md\">let grid = \u2026; grid[0][0] = 99<\/td>\n<td data-col-size=\"lg\">Use var if you need to change<\/td>\n<td data-col-size=\"md\">Immutable<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"xl\">Using fixed indices without validation<\/td>\n<td data-col-size=\"md\">matrix[5][5]<\/td>\n<td data-col-size=\"lg\">Use indices.contains or safe subscript<\/td>\n<td data-col-size=\"md\">Out-of-bounds \u2192 crash<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">8. Quick Reference \u2013 Most Useful 2D Array Operations<\/h3>\n<div>\n<div dir=\"auto\">\n<table dir=\"auto\">\n<thead>\n<tr>\n<th data-col-size=\"md\">Goal<\/th>\n<th data-col-size=\"lg\">Recommended code<\/th>\n<th data-col-size=\"md\">Notes<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td data-col-size=\"md\">Create empty 2D grid<\/td>\n<td data-col-size=\"lg\">Array(repeating: Array(repeating: 0, count: cols), count: rows)<\/td>\n<td data-col-size=\"md\">Classic way<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Safe element access<\/td>\n<td data-col-size=\"lg\">matrix[safe: row]?[safe: col] ?? default<\/td>\n<td data-col-size=\"md\">With safe subscript extension<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Loop with row &amp; column indices<\/td>\n<td data-col-size=\"lg\">for r in matrix.indices { for c in matrix[r].indices { \u2026 } }<\/td>\n<td data-col-size=\"md\">Most explicit &amp; safe<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Print nicely<\/td>\n<td data-col-size=\"lg\">matrix.map { $0.map(String.init).joined(separator: &#8221; &#8220;) }.joined(separator: &#8220;\\n&#8221;)<\/td>\n<td data-col-size=\"md\">Quick debug print<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Get row<\/td>\n<td data-col-size=\"lg\">matrix[2]<\/td>\n<td data-col-size=\"md\">Returns Array (copy)<\/td>\n<\/tr>\n<tr>\n<td data-col-size=\"md\">Get column (trickier)<\/td>\n<td data-col-size=\"lg\">(0..&lt;matrix.count).map { matrix[$0][col] }<\/td>\n<td data-col-size=\"md\">No built-in column access<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div><\/div>\n<\/div>\n<\/div>\n<h3 dir=\"auto\">9. Small Practice \u2013 Try these<\/h3>\n<ol dir=\"auto\">\n<li>Create a 4\u00d75 grid filled with zeros \u2192 Set position [1][2] = 99 \u2192 Print the grid row by row<\/li>\n<li>Create a 3\u00d73 tic-tac-toe board \u2192 Place &#8220;X&#8221; in center \u2192 Place &#8220;O&#8221; in all four corners \u2192 Print the board with nice separators<\/li>\n<li>Create a sales table (3 products \u00d7 4 months) \u2192 Print it like a real table with headers<\/li>\n<\/ol>\n<p dir=\"auto\">Paste your code here if you want feedback or cleaner versions!<\/p>\n<p dir=\"auto\">What would you like to explore next about arrays?<\/p>\n<ul dir=\"auto\">\n<li><strong>Sorting<\/strong> 2D arrays (by row, by column, custom)<\/li>\n<li><strong>Transposing<\/strong> a matrix (rows \u2194 columns)<\/li>\n<li><strong>Flattening<\/strong> 2D \u2192 1D and vice versa<\/li>\n<li>Multidimensional arrays in <strong>SwiftUI<\/strong> (grids, tables)<\/li>\n<li>Arrays vs <strong>ArraySlice<\/strong> vs <strong>ContiguousArray<\/strong><\/li>\n<li>Or move to another topic (dictionaries, sets, optionals\u2026)<\/li>\n<\/ul>\n<p dir=\"auto\">Just tell me \u2014 we\u2019ll keep going in the same clear, detailed, patient style \ud83d\ude0a<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. What is a Multidimensional Array? A multidimensional array is simply an array of arrays. In other words: You have an outer array Each element of the outer array is itself an array So&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[76],"tags":[],"class_list":["post-2665","post","type-post","status-publish","format-standard","hentry","category-swift"],"_links":{"self":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2665","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/comments?post=2665"}],"version-history":[{"count":1,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2665\/revisions"}],"predecessor-version":[{"id":2666,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/posts\/2665\/revisions\/2666"}],"wp:attachment":[{"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/media?parent=2665"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/categories?post=2665"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demo.materiamedica.net\/demo6\/wp-json\/wp\/v2\/tags?post=2665"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}