Skip to content

Instantly share code, notes, and snippets.

@rklemme
Last active December 12, 2015 12:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rklemme/4771651 to your computer and use it in GitHub Desktop.
Save rklemme/4771651 to your computer and use it in GitHub Desktop.
Sample matrix with abstraction of rows and columns. This can certainly be improved, it's just to convey an idea.
#!/usr/bin/ruby
class Matrix
def initialize(row_headers, col_headers)
@row_headers = row_headers
@col_headers = col_headers
end
def [](row, col)
data[index(row, col)]
end
def []=(row, col, val)
# data[index(row, col)] = val
idx = index(row, col)
val.nil? ? data.delete(idx) : data[idx] = val
end
def row(row)
Row.new(self, row)
end
def column(col)
Column.new(self, col)
end
def each_row
@row_headers.each do |idx|
yield row(idx)
end
self
end
def each_column
@col_headers.each do |idx|
yield col(idx)
end
self
end
def row_headers
@row_headers.dup
end
def col_headers
@col_headers.dup
end
private
def index(row, col)
# @row_headers.index(row) * @col_headers.size + @col_headers.index(col)
"#{row}:#{col}"
end
def data
# @data ||= []
@data ||= {}
end
end
class MatrixPart
attr_reader :matrix
def initialize(matrix)
@matrix = matrix
end
def [](item)
matrix[*indexes(item)]
end
def []=(item, val)
matrix[*indexes(item)] = val
end
include Enumerable
def each
each_address do |row, col|
yield matrix[row, col]
end
self
end
end
class Row < MatrixPart
def initialize(matrix, row_id)
super(matrix)
@row_id = row_id
end
private
def indexes(col_id)
return @row_id, col_id
end
def each_address
matrix.col_headers.each {|col_id| yield @row_id, col_id}
self
end
end
class Column < MatrixPart
def initialize(matrix, col)
super(matrix)
@col_id = col
end
private
def indexes(row_id)
return row_id, @col_id
end
def each_address
matrix.row_headers.each {|row_id| yield row_id, @col_id}
self
end
end
if $0 == __FILE__
require 'pp'
puts "test"
m = Matrix.new(%w{a b c}, %w{1 2 3 4})
m["a", "1"] = 123
m["b", "4"] = 123
row = m.row("a")
row["1"] = 22
row.each {|x| p x}
pp m
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment