problem making an array of arrays (of arrays)

C

Cec Tre

Hey, bit of a ruby noob here :)

First, hello ruby-forum community.

So, here is my problem. I want to create a 5x5 grid, however, each of
the 'cells' in the grid should be able to hold a variety of values.

Firstly, I started off with this:

@row_1 = ['x','x','x','x','x']
@row_2 = ['x','x','x','x','x']
@row_3 = ['x','x','x','x','x']
@row_4 = ['x','x','x','x','x']
@row_5 = ['x','x','x','x','x']
@grid = [@row_1,@row_2,@row_3,@row_4,@row_5]

So, obviously this creates a 5x5 grid, in which each of the 'cells' or
@row_1..5[1..5] == 'x'.

I used to just alter the string value in each cell by using:

@grid[y][x] = 'new string'

But, I ultimately want each cell to be an array.. So that I can push and
pop their values as they change, and then the grid will always display
the last value in the array, by using:

@row_1 = [array.last,array1.last,array2.last,array3.last]
#etc etc etc...

My problem then is, that I have a different variable name for each of
the five points in each of the five rows.

So, the solution I really want is:

Is it possible to have a variable called, say... cellxx ... Then, some
piece of code that alters the xx part of the actual variable name
itself?

Because, I'm going about implementing cell00, cell01, cell02, cell03 etc
etc each as an array and my code is getting messy.

Please is there an (easier) way, to do what I want?

Sorry for the length of this, you can tell i'm new to ruby :) Thanks!
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

Hey, bit of a ruby noob here :)

First, hello ruby-forum community.

So, here is my problem. I want to create a 5x5 grid, however, each of
the 'cells' in the grid should be able to hold a variety of values.

Firstly, I started off with this:

@row_1 = ['x','x','x','x','x']
@row_2 = ['x','x','x','x','x']
@row_3 = ['x','x','x','x','x']
@row_4 = ['x','x','x','x','x']
@row_5 = ['x','x','x','x','x']
@grid = [@row_1,@row_2,@row_3,@row_4,@row_5]

So, obviously this creates a 5x5 grid, in which each of the 'cells' or
@row_1..5[1..5] == 'x'.

I used to just alter the string value in each cell by using:

@grid[y][x] = 'new string'

But, I ultimately want each cell to be an array.. So that I can push and
pop their values as they change, and then the grid will always display
the last value in the array, by using:

@row_1 = [array.last,array1.last,array2.last,array3.last]
#etc etc etc...

My problem then is, that I have a different variable name for each of
the five points in each of the five rows.

So, the solution I really want is:

Is it possible to have a variable called, say... cellxx ... Then, some
piece of code that alters the xx part of the actual variable name
itself?

Because, I'm going about implementing cell00, cell01, cell02, cell03 etc
etc each as an array and my code is getting messy.

Please is there an (easier) way, to do what I want?

Sorry for the length of this, you can tell i'm new to ruby :) Thanks!

Personally, I think I would opt for nested classes in this case, but if I
understand your problem correctly, then this should do what you are asking.


# the 2d array of elements that are arrays
# each currently containing it's yx location as a string
array = [[["00"], ["01"], ["02"], ["03"], ["04"]],
[["10"], ["11"], ["12"], ["13"], ["14"]],
[["20"], ["21"], ["22"], ["23"], ["24"]],
[["30"], ["31"], ["32"], ["33"], ["34"]],
[["40"], ["41"], ["42"], ["43"], ["44"]]]

# go through the array and set variables to reference the individual cells
array.each_with_index do |row,y|
row.each_with_index do |element,x|
instance_variable_set "@array#{y}#{x}" , element
end
end

# show that we can access it as you describe
@array00 << 'a'
@array01 << 'b'
@array11 << 'c'
@array22 << 'd'
@array33 << 'e'
@array43 << 'f'
@array44 << 'g'

# format the output so that it is easier to see what we did
puts '['
array.each do |row|
print ' [ '
row.each do |col|
printf '%-12s , ' , col.inspect
end
puts ' ]'
end
puts ']'
 
P

Phrogz

So, here is my problem. I want to create a 5x5 grid, however, each of
the 'cells' in the grid should be able to hold a variety of values.

rb(main):001:0> a = Array.new(5){ Array.new(5) }
=> [[nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil,
nil, nil, nil], [nil, nil, nil, nil, nil], [nil, nil, nil, nil, nil]]

irb(main):002:0> require 'pp'; pp a
[[nil, nil, nil, nil, nil],
[nil, nil, nil, nil, nil],
[nil, nil, nil, nil, nil],
[nil, nil, nil, nil, nil],
[nil, nil, nil, nil, nil]]
=> nil

That says:
Create an array with 5 elements; for each of the five elements, call
this block and use the return value for the value of the element. When
you call the block, create a new array of 5 empty elements.

You also can use the index of the array in your block. For example:

irb(main):009:0> CHARS = ('A'..'Z').to_a
=> ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]

irb(main):010:0> excel = Array.new(5){ |row| Array.new(5){ |col|
"#{CHARS[col]}#{row+1}" } }
=> [["A1", "B1", "C1", "D1", "E1"], ["A2", "B2", "C2", "D2", "E2"],
["A3", "B3", "C3", "D3", "E3"], ["A4", "B4", "C4", "D4", "E4"], ["A5",
"B5", "C5", "D5", "E5"]]

irb(main):012:0> pp excel
[["A1", "B1", "C1", "D1", "E1"],
["A2", "B2", "C2", "D2", "E2"],
["A3", "B3", "C3", "D3", "E3"],
["A4", "B4", "C4", "D4", "E4"],
["A5", "B5", "C5", "D5", "E5"]]
=> nil

So, the solution I really want is:

Is it possible to have a variable called, say... cellxx ... Then, some
piece of code that alters the xx part of the actual variable name
itself?

That's a bad solution. Programmatically create or modify your array in
loops; don't create explicit temporary variables you don't need.
Here's another solution:

irb(main):013:0> a = []
=> []

irb(main):014:0> 5.times{ |i| a = [] }
=> 5

irb(main):015:0> a
=> [[], [], [], [], []]

irb(main):016:0> a[2][3] = "hi"
=> "hi"

irb(main):017:0> a
=> [[], [], [nil, nil, nil, "hi"], [], []]
 
R

Robert Klemme

2010/3/19 Cec Tre said:
Hey, bit of a ruby noob here :)

First, hello ruby-forum community.

So, here is my problem. I want to create a 5x5 grid, however, each of
the 'cells' in the grid should be able to hold a variety of values.

Firstly, I started off with this:

=A0 =A0@row_1 =3D ['x','x','x','x','x']
=A0 =A0@row_2 =3D ['x','x','x','x','x']
=A0 =A0@row_3 =3D ['x','x','x','x','x']
=A0 =A0@row_4 =3D ['x','x','x','x','x']
=A0 =A0@row_5 =3D ['x','x','x','x','x']
=A0 =A0@grid =3D [@row_1,@row_2,@row_3,@row_4,@row_5]

So, obviously this creates a 5x5 grid, in which each of the 'cells' or
@row_1..5[1..5] =3D=3D 'x'.

I used to just alter the string value in each cell by using:

=A0 =A0@grid[y][x] =3D 'new string'

But, I ultimately want each cell to be an array.. So that I can push and
pop their values as they change, and then the grid will always display
the last value in the array, by using:

=A0 =A0@row_1 =3D [array.last,array1.last,array2.last,array3.last]
=A0 =A0#etc etc etc...

My problem then is, that I have a different variable name for each of
the five points in each of the five rows.

So, the solution I really want is:

Is it possible to have a variable called, say... cellxx ... Then, some
piece of code that alters the xx part of the actual variable name
itself?

Because, I'm going about implementing cell00, cell01, cell02, cell03 etc
etc each as an array and my code is getting messy.

It's not a good idea to encode what is an index into the variable
name. Rather you should use proper indexing.
Please is there an (easier) way, to do what I want?

grid =3D Array.new(5) { Array.new(5) { [] } }

Now you can do

irb(main):006:0> grid[1][2]
=3D> []
irb(main):007:0> grid[1][2] << "dat"
=3D> ["dat"]
irb(main):008:0> grid[1][2]
=3D> ["dat"]
irb(main):009:0> grid[1][2] << "foo"
=3D> ["dat", "foo"]
irb(main):010:0> grid[1][2]
=3D> ["dat", "foo"]

Kind regards

robert

--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top