lib/grid_struct.rb in grid_struct-0.0.1 vs lib/grid_struct.rb in grid_struct-0.1.0

- old
+ new

@@ -24,28 +24,19 @@ @store[index] = yield(value, row_column[:row], row_column[:column]) end return self end - def map_row!(n) - @columns.times.each do |column| - index = get_index(n,column) - value = @store[index] - @store[index] = yield(value,column) - end - return self + def map_row!(n, &block) + return map_line!(n, @columns, true, &block) end - def map_column!(n) - @rows.times.each do |row| - index = get_index(row,n) - value = @store[index] - @store[index] = yield(value,row) - end - return self + def map_column!(n, &block) + return map_line!(n, @rows, false, &block) end + def each @store.fill(nil,@store.size...size).each.with_index do |value, index| row_column = get_row_column_at(index) yield(value,row_column[:row],row_column[:column]) end @@ -77,30 +68,12 @@ sub_columns = (@columns / columns.to_f).ceil sub_row = index / sub_columns sub_column = index - (sub_row * sub_columns) - indexes = [] - rows.times.each do |r| - start_index = (r * @columns) + - (sub_row * rows * @columns) + - (sub_column * columns) - end_index = start_index + columns + indexes = retrieve_sliced_indexes(rows,columns,sub_row,sub_column) - start_row = get_row_column_at(start_index)[:row] - end_row = get_row_column_at(end_index)[:row] - - if start_row != end_row - extras = [0,(end_index - @columns)].max % @columns - end_index -= extras - end - - final_row_indexes = (start_index...end_index).to_a - final_row_indexes.fill(nil,final_row_indexes.size...columns) - indexes += final_row_indexes - end - return GridStruct::Selector.new(self, *indexes).dimensions(rows,columns) end def row(n) start_index = (n * @columns) @@ -137,12 +110,54 @@ def ==(other) @store == other.instance_variable_get(:@store) end + def within_bounds?(row,column) + row_within_bounds?(row) && column_within_bounds?(column) + end + protected + def fit_selection_within_same_row(start_index, end_index) + start_row = get_row_column_at(start_index)[:row] + end_row = get_row_column_at(end_index)[:row] + + if start_row != end_row + extras = [0,(end_index - @columns)].max % @columns + end_index -= extras + end + + return start_index...end_index + end + + def retrieve_sliced_indexes(rows, columns, sub_row, sub_column) + rows.times.inject([]) do |memo, r| + start_index = (r * @columns) + + (sub_row * rows * @columns) + + (sub_column * columns) + end_index = start_index + columns + + final_row_indexes = fit_selection_within_same_row(start_index, end_index).to_a + final_row_indexes.fill(nil,final_row_indexes.size...columns) + + memo += final_row_indexes + end + end + + def line_within_bounds?(n, axis_size) + n >= 0 && n < axis_size + end + + def row_within_bounds?(row) + line_within_bounds?(row, @rows) + end + + def column_within_bounds?(column) + line_within_bounds?(column, @columns) + end + def get_index(row,column) (row * @columns) + column end def get_row_column_at(index) @@ -154,33 +169,38 @@ def diagonal_builder(coordinates, row_direction = 1, column_direction = 1, diagonal_indexes = [], action = :push) row = coordinates[:row] column = coordinates[:column] index = get_index(row,column) - if !diagonal_indexes.include?(index) && - row >= 0 && - column >= 0 && - row < @rows && - column < @columns - + if !diagonal_indexes.include?(index) && within_bounds?(row, column) diagonal_indexes.method(action).call(get_index(row,column)) - diagonal_builder({ row: row - (row_direction * 1), - column: column - (column_direction * 1) }, - row_direction, - column_direction, - diagonal_indexes, - :unshift) - - diagonal_builder({ row: row + (row_direction * 1), - column: column + (column_direction * 1) }, - row_direction, - column_direction, - diagonal_indexes, - :push) - + fetch_diagonal_index(row, column, row_direction, column_direction, diagonal_indexes, -1) + fetch_diagonal_index(row, column, row_direction, column_direction, diagonal_indexes, 1) end return diagonal_indexes + end + + def fetch_diagonal_index(row, column, row_direction, column_direction, diagonal_indexes, sign) + row = row + sign * row_direction + column = column + sign * column_direction + action = sign > 0 ? :push : :unshift + + diagonal_builder({ row: row, + column: column }, + row_direction, + column_direction, + diagonal_indexes, + action) + end + + def map_line!(n, other_axis_size, is_row) + other_axis_size.times.each do |other_axis| + index = is_row ? get_index(n,other_axis) : get_index(other_axis,n) + value = @store[index] + @store[index] = yield(value,other_axis) + end + return self end end