public
Last active

Sample matrix with abstraction of rows and columns. This can certainly be improved, it's just to convey an idea.

  • Download Gist
matrix.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
#!/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

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.