GridStruct
Manipulate grid like structure in Ruby.
Installation
Add this line to your application's Gemfile:
gem 'grid_struct'
And then execute:
$ bundle
Or install it yourself as:
$ gem install grid_struct
Usage
Create a GridStruct
In order to create a grid, you have to pass a 2 arguments:
rows
: the number of rows your grid has (the height of the grid)columns
: the number columns your grid has (the width of the grid)
rows = 9
columns = 5
grid = GridStruct.new(rows, columns)
grid.size
grid.columns
grid.rows
It is possible to initialize the array with pre-set values.
The 3rd argument must be an array.
If we want to initialize the following grid:
+---+---+---+
| X | O | O |
+---+---+---+
| X | x | O |
+---+---+---+
| O | X | O |
+---+---+---+
Use the following array structure:
grid_data = ['X','O','O','X','X','O','O','X','O']
tic_tac_toe = GridStruct.new(3, 3, grid_data)
GridStruct
actually store your values extactly the same way, in a 1-dimentional array.
Basics
Now you know how to create grids, it's time to learn how to use our new data structure.
Read the data store
As mentionned above, your data are stored in a 1-dimentional array.
tic_tac_toe.store
GridStruct.new(9,9).store
As you can see, the store
always starts as an empty array unless you decide to pre-fill the grid.
Set value
To set a value, pass the row and column you want to fill, and a block that will return the value
GridStruct#set(row, column) { value }
sudoku_grid = GridStruct.new(9,9)
sudoku_grid.set(0,0) { 'Hello World' }
sudoku_grid.store
sudoku_grid.set(1,0) { 'Row: 1, Col: 0' }
sudoku_grid.store
Get value
To get a value at a specific coordinate, use th get
method.
GridStruct#get(row, column) # => value
sudoku_grid.get(1,0)
Iterate
You can iterate through the grid using the each method
GridStruct#each { |value, row, column| # Do something }
Mass update
Grid
Incase you need to update each element within the grid, use the map!
method
GridStruct#map! { |value, row, column| # Return new value }
grid = GridStruct.new(3,3)
grid.map! { |value, row, column| (row * grid.columns) + column }
grid.store
Row
You can update a specific row if needed, for example, if we want to update the middle row
GridStruct#map_row! { |value, column| # Return new value }
+---+---+---+
| 0 | 1 | 2 |
+---+---+---+
Update this row → | 3 | 4 | 5 |
+---+---+---+
| 6 | 7 | 8 |
+---+---+---+
grid.map_row!(1) { |value| value * 10 }
grid.store
Column
You can update a specific row if needed, for example, if we want to update the middle row
GridStruct#map_column! { |value, row| # Return new value }
Update this columns
↓
+---+---+---+
| 0 | 1 | 2 |
+---+---+---+
| 3 | 4 | 5 |
+---+---+---+
| 6 | 7 | 8 |
+---+---+---+
grid.map_column!(2) { |value| value * 10 }
grid.store
Selectors
Selector gives you access to line of values within the grid, and allows you to
only act on that line. Each selector return a (or an array of) GridStruct::Selector.
Overview
A selector has the following instances:
grid
: The grid it is selecting fromindexes
: An array of indexes mapping to the selected values in the grid store
grid = GridStruct.new(3,3)
grid.map! do |value, row, column|
(row * grid.columns + column) * 10
end
grid.row(0)
You can retrieve and update values using []
. It will map the action to the grid.
first_row = grid.row(0)
first_row.to_a
first_row[0]
first_row[1]
first_row[2]
first_row[0] = -100
grid.to_a
Row
To select a specific row, use the method row
GridStruct#row(row_number)
rows = []
grid.rows.times.each do |row_index|
rows[row_index] = grid.row(row_index)
end
Column
To select a specific column, use the method column
GridStruct#column(column_number)
columns = []
grid.columns.times.each do |column_index|
columns[column_index] = grid.column(column_index)
end
Diagonals
The diagonals retrieval works slightly differently from the two previous methods.
In order to retrieve diagonals, you must provide the coordinates of a cell in the grid. This will retrieve the diagonals that cross through that specific cell.
The returned array can be of size 0 (no diagonals found, for example, in a grid of size 1), 1 (when retrieving diagonals from the corners of the grid) or 2.
GridStruct#diagonals(1,1) # => [#<GridStruct::Selector ...>, #<GridStruct::Selector ...>]
diagonals = grid.diagonals(1,1)
diagonals.first.to_a
diagonals.last.to_a
corner_diagonal = grid.diagonals(0,0)
corner_diagonal.size
corner_diagonal.first.to_a
Slice
Imagine a slice as a projection of a section of your grid.
Use the slice
method to access a single slice.
GridStruct#slice(slice_index, rows: slice_rows, columns: slice_columns) # => #<GridStruct::Selector ...>
In the following example, we are manipulating a sudoku grid, and we want to access the middle 3x3 square
sudoku_grid = GridStruct.new(9,9)
sudoku_grid.map! do |v, r, c|
(r * sudoku_grid.columns) + c + 1
end
sudoku_grid.slice(4, rows: 3, columns: 3)
Use the each_slice
method to go through each slices
GridStruct#each_slice(slice_rows,slice_columns) { |slice, slice_index| # Do something }
sudoku_grid.each_slice(3,3) do |slice, index|
end
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request