Skip to content

Instantly share code, notes, and snippets.

@polarblau
Created September 1, 2014 07:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save polarblau/f55646d6d9434d4e16bb to your computer and use it in GitHub Desktop.
Save polarblau/f55646d6d9434d4e16bb to your computer and use it in GitHub Desktop.
Helper class for work with two–dimensional arrays
class Matrix
members: [[]]
@fromArray = (array, width)->
chunks = []
for _, index in array by width
chunks.push array.slice(index, index + width)
new Matrix(chunks)
constructor: (width, height)->
if !height and isArray(width)
@members = width
else
@resize(width, height)
isEmpty: ->
@members.length is 1 and not @members[0].length
width: ->
@members[0].length
height: ->
@members.length
slice: (x, y, width, height)->
if x > @width() or y > @height()
throw new Error('Coordinates out of bounds.')
partial = @members.slice(y, y + height)
partial[index] = row.slice(x, x + width) for row, index in partial
matrix = new Matrix(partial)
matrix.resize(width, height)
matrix
resize: (width, height)=>
# reduce height
@members = @members.splice(0, height) if height < @height()
# increase height
@members[rowIndex] = Array(width) for rowIndex in [@height()...height]
# adjust width
if @width() > width
row.splice(0, width) for row in @members
else if @width() < width
for row in @members
row.push undefined while row.length < width
return this
join: (other, x=0, y=0)=>
# increase size if necessary
width = Math.max(x + other.width(), @width())
height = Math.max(y + other.height(), @height())
@resize(width, height)
# join members at correct position
members = @members
other.forEachRow (row, rowIndex)=>
for item, itemIndex in row
members[rowIndex + y][itemIndex + x] = item
return this
forEachRow: (iterator)->
for row, x in @members
iterator.call(this, row, x)
forEachMember: (iterator)->
@forEachRow (row, x)=>
for element, y in row
iterator.call(this, element, x, y)
toArray: ->
@members
toString: ->
maxLength = 0
@forEachMember (element)->
if (length = "#{element}".length) > maxLength
maxLength = length
rows = for row in @members
"[#{(pad(element, maxLength) for element in row).join(', ')}]"
rows.join("\n")
#
pad = (string, length, padding = " ")->
string = "#{string}"
string = "#{padding}#{string}" while string.length < length
string
isArray = (object)->
Object.prototype.toString.call(object) is '[object Array]'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment