In Scala 3.3 we can create 2D spaces with nested lists or tuples. For small regions, nested collections are helpful. For large ones, a more memory-efficient representation is needed.
In Scala, we build 1 to 5 dimensional arrays with the Array.ofDim
function. This can be useful, but often using 1D arrays can be sufficient.
Here we create a List
with two nested Lists within it. So this example shows a grid of 2 by 2 Ints. With println
we can display all elements.
Length
returns the count of rows (not of all elements) when using nested lists. Each nested List
counts as just 1.foreach
we can nest lambda expressions.object Program { def main(args: Array[String]): Unit = { // Create list of nested lists. val elements = List(List(20, 30), List(40, 50)) // Print elements. println(elements) println(elements.length) // Access top left element. val topLeft = elements(0)(0) println(s"Top left = $topLeft") // Loop over all elements with a foreach call. elements.foreach(_.foreach(println(_))) } }List(List(20, 30), List(40, 50)) 2 Top left = 20 20 30 40 50
Here we form a List
of tuples (pairs). We add another pair to the beginning of our list, creating a new, modified list. We then enumerate our list with for.
object Program { def main(args: Array[String]): Unit = { // Create list of tuples. val elements = List((10, 20), (30, 40), (50, 60)) // Add a tuple to the start of the list. val modified = (0, 10) :: elements // Loop over indices in the list. for (pair <- modified) { // Get both parts of the tuple. val left = pair._1 val right = pair._2 // Print parts of the tuple. println(s"Left = $left; Right = $right") } } }Left = 0; Right = 10 Left = 10; Right = 20 Left = 30; Right = 40 Left = 50; Right = 60
Array.ofDim
Here is a 2D array. This is a more efficient, low-level representation of two-dimensional data. We create the array with the Array.ofDim
function.
Array.ofDim
are the row count and column count. We must provide a type argument.apply()
and update()
functions to change cells in our 2D array. With apply we access rows—these are 1D arrays.update()
to change the value of cells. Finally we use nested for
-loops to print all Int
values.object Program { def main(args: Array[String]): Unit = { // Create a 2D array of 3 rows and 3 columns. val numbers = Array.ofDim[Int](3, 3) // Update first row cells. val result1 = numbers.apply(0) result1.update(0, 900) result1.update(1, 800) result1.update(2, 700) // Update second row. val result2 = numbers.apply(1) result2.update(0, -1) // Update third row. val result3 = numbers.apply(2) result3.update(0, -2) // Loop over rows. for (row <- numbers) { // Loop over cells in rows. // ... Display all numbers on lines. for (cell <- row) { print(cell) print(" ") } println() } } }900 800 700 -1 0 0 -2 0 0
Often, small 2D collections can be represented in simple, straightforward ways in Scala. We can nest Lists within Lists, or even nest related types like classes or tuples.