# Table<T> 2d array

Tweet monkey-x code-archives algorithms
(Posted 9 months ago)

A convenient 2d array with neat features.

Features include the ability to get/set/iterate through individual rows or columns, native 1d data access, 2d data accessors (Get/Set), and support for exceptions to prevent undefined behavior on the desktop target.

table.monkey

``````Class Table<T>
Field Width:Int, Height:Int
Field data:T[]

'Summary:  Creates a new data table of the specified size.
Method New(width:Int, height:Int)
If width <= 0 or height <= 0
Print("Warning:  Table of invalid dimensions defined. (" + width + "," + height + ")")
Throw New TableInitError()
Else
Width = width; Height = height
data = data.Resize(width * height)
End If
End Method

'Summary:  Returns the table to uninitialized values.
Method Clear:Void()
'I wonder if this is a good idea
Local newdata:T[]
newdata = newdata.Resize(Width * Height)
data = newdata
End Method

'Summary:  Returns the value at (x,y).
Method Get:T(x:Int, y:Int)
#If CONFIG="debug"
If (0 > x) Or (x >= Width) Then Print("Warning: X is out of range. " + x)
If (0 > y) Or (y >= Height) Then Print("Warning: Y is out of range. " + y)
If (0 > x) Or (x >= Width) Or (0 > y) Or (y >= Height)
Throw New TableIndexOutOfRangeError()
End If
#EndIf

Return data[y * Width + x]
End Method

'Summary:  Sets the value at (x,y).
Method Set:Void(value:T, x:Int, y:Int)
#If CONFIG="debug"
If (0 > x) Or (x >= Width) Then Print("Warning: X is out of range. " + x)
If (0 > y) Or (y >= Height) Then Print("Warning: Y is out of range. " + y)
If (0 > x) Or (x >= Width) Or (0 > y) Or (y >= Height)
Throw New TableIndexOutOfRangeError()
End If
#EndIf

data[y * Width + x] = value
End Method

'Summary:  Returns an array representing a row in the table structure.
Method Row:T[] (index:Int)
If (0 > index) Or (index >= Height) Then Throw New TableIndexOutOfRangeError()

Local out:T[]
out = out.Resize(Width)

For Local i:Int = 0 Until Width
out[i] = data[ (index * Width) + i]
Next

Return out
End Method
'Summary:  Returns an array representing a column in the table structure.
Method Column:T[] (index:Int)
If (0 > index) Or (index >= Width) Then Throw New TableIndexOutOfRangeError()

Local out:T[]
out = out.Resize(Height)

For Local i:Int = 0 Until Height
out[i] = data[ (i * Width) + index]
Next

Return out
End Method

'Summary:  Sets a row of values to the ones in [value].
Method SetRow:Void(value:T[], index:Int)
For Local i:Int = 0 Until Width
data[ (index * Width) + i] = value[i]
Next
End Method
'Summary:  Sets a column of values to the ones in [value].
Method SetColumn:Void(value:T[], index:Int)
For Local i:Int = 0 Until Height
data[ (i * Width) + index] = value[i]
Next
End Method

'Summary:  Provides an object enumerating all rows in the table.
Method Rows:TableRows<T>()
Return New TableRows<T>(Self)
End Method
'Summary:  Provides an object enumerating all columns in the table.
Method Columns:TableColumns<T>()
Return New TableColumns<T>(Self)
End Method

End Class

'Summary:  Thrown when table doesn't init correctly.
Class TableInitError Extends Throwable
End Class
'Summary:  Thrown when a row or column value is out of range.
Class TableIndexOutOfRangeError Extends Throwable
End Class

'The below classes are for allowing EachIn enumeration of rows and columns.
'#Region Row/Column Enumerators
Class TableRows<T>
Private
Field table:Table<T>

Public
Method New(table:Table<T>)
Self.table = table
End

Method ObjectEnumerator:RowEnumerator<T>()
Return New RowEnumerator<T>(table)
End
End Class

Class TableColumns<T>
Private
Field table:Table<T>

Public
Method New(table:Table<T>)
Self.table = table
End

Method ObjectEnumerator:ColumnEnumerator<T>()
Return New ColumnEnumerator<T>(table)
End
End Class

Class RowEnumerator<T>
Private
Field table:Table<T>
Field index:Int

Public
Method New(table:Table<T>)
Self.table = table
End Method

Method HasNext:Bool()
Return index < table.Height
End Method

Method NextObject:T[] ()
index+=1
Return table.Row(index - 1)
End Method
End Class

Class ColumnEnumerator<T>
Private
Field table:Table<T>
Field index:Int

Public
Method New(table:Table<T>)
Self.table = table
End Method

Method HasNext:Bool()
Return index < table.Width
End Method

Method NextObject:T[] ()
index+=1
Return table.Column(index - 1)
End Method
End Class
'#End Region``````

Example

``````Import table

Function Main:Int()
'Makes a 5x5 table
Local t:=New Table<Int>(5,5)

'Initialize each cell in a row to the same value?
Local rowNum:Int
For local row:= EachIn t.Rows()
For local i:Int = 0 until t.Width 'We could've also said eachIn row, or until row.Length()
row[i] = rowNum
Next
rowNum+=1
Next

'Randomize the entire table.
For local i:Int = 0 until t.data.Length
t.data[i] = Rnd(\$FFFFFFF)
Next

'Gimme a copy of column 3.
Local col:Int[] = t.Column(3)

'Let's change all of column 3 to 0.
For local i:Int = 0 until col.Length
col[i] = 0
Next
t.SetColumn(col, 3)

'Catching an out of range index.
Try
Local invalid:Int = t.Get(-1,-1)
Catch ex:TableIndexOutOfRangeError
Print ("Invalid cell!")
End Try
End Function``````