2 dimensional array

Dear all

I worked for quite some hours and i googled the two dimensional array in
ruby and yet my problem is partially solved

I want to declare 2-dimensional arrays it has 6 columns but uknow number
of columns.
i tried this way
array = [][] # did not work
array = [[],[]] # it works but only for two elements.

another question I believe the answer is no but i want to confirm
can we have multi-dimensional hash? :slight_smile:

any one has any idea to share
Regards
Shuaib

···

--
Posted via http://www.ruby-forum.com/.

Alle mercoledì 17 ottobre 2007, Shuaib Zahda ha scritto:

Dear all

I worked for quite some hours and i googled the two dimensional array in
ruby and yet my problem is partially solved

I want to declare 2-dimensional arrays it has 6 columns but uknow number
of columns.
i tried this way
array = # did not work
array = [,] # it works but only for two elements.

another question I believe the answer is no but i want to confirm
can we have multi-dimensional hash? :slight_smile:

any one has any idea to share
Regards
Shuaib

Ruby doesn't have 2-dimensional arrays, but you can use nested arrays to
achieve the same effect. If you want an array with 6 columns and any number
of rows, you can do something like:

a = Array.new(6){}

This creates an array of 6 elements, each of one contains an array. Each
element represents a column. The entries of the column are stored into the
nested array.

You can store entries like this:

a[2][3] = 1

This sets the element 3 of the row 2 to be one.

Of course, this approach allows you to have columns with different sizes. For
example, since each clumn is an array, you can do this:

a[1] << 2

This increases the size of the column 1 by one, by appending an element to it.
If you want to avoid this, you can wrap the 2d array in a class:

class Array2D

  def initialize cols, default = nil
    @data = Array.new(cols){}
    @default = default
  end

  def append_row
    @data.each{|c| c << @default}
  end

  def (col, row=nil)
    if row then @data[col][row]
    else @data[col].dup
    end
  end

  def =(col, row, value)
    raise IndexError if col >= @data.size or row >= @data[0].size
    @data[col][row]=value
  end

  def each_col
    @data.each{|c| yield c.dup}
  end

  def each
    @data.each do |c|
      c.each{|i| yield i}
    end
  end

end

USAGE:

a = Array2D.new 3, :a
3.times{a.append_row}
a[0, 0] = :b
a[1, 2] = :c
p a[0]
p a[1]
p a[2]

Regarding your second question, what do you mean by "multidimensional hash"?

Stefano

I want to declare 2-dimensional arrays it has 6 columns but uknow number
of columns.
i tried this way
array = # did not work
array = [,] # it works but only for two elements.

There is no such thing as a 2-dimensional array in Ruby (not in the
core, anyhow). Using core objects, you can instead create an array of
arrays (as you have done above).

Here's an example of some code that automatically creates rows with 6
nil values each time you ask for a row:

  class SixColArray < Array
    def initialize( num_rows=0 )
      # Simply asking for a row ensures it and all lesser rows exist
      self[num_rows-1] if num_rows > 0
    end
    def ( row_number )
      unless row = super
        # Create a new row with 6 'column' arrays
        row = self[ row_number ] = Array.new(6)
        # Ensure lower row numbers exist by asking for them
recursively
        self[ row_number - 1 ] if row_number > 0
      end
      row
    end
  end

  require 'pp'
  six_col = SixColArray.new( 4 )
  six_col[ 0 ][ 3 ] = 42
  six_col[ 3 ][ 1 ] = 15
  pp six_col
  #=> [[nil, nil, nil, 42, nil, nil],
  #=> [nil, nil, nil, nil, nil, nil],
  #=> [nil, nil, nil, nil, nil, nil],
  #=> [nil, 15, nil, nil, nil, nil]]

  # A new row is created on the fly
  six_col[ 4 ][ 5 ] = 99
  pp six_col
  #=> [[nil, nil, nil, 42, nil, nil],
  #=> [nil, nil, nil, nil, nil, nil],
  #=> [nil, nil, nil, nil, nil, nil],
  #=> [nil, 15, nil, nil, nil, nil],
  #=> [nil, nil, nil, nil, nil, 99]]

  # There is no limit on the number of columns in a row
  # ...or the type of values for each slot
  six_col[ 2 ][ 8 ] = 'ow'
  pp six_col
  #=> [[nil, nil, nil, 42, nil, nil],
  #=> [nil, nil, nil, nil, nil, nil],
  #=> [nil, nil, nil, nil, nil, nil, nil, nil, "ow"],
  #=> [nil, 15, nil, nil, nil, nil],
  #=> [nil, nil, nil, nil, nil, 99]]

If you want something more robust (for example ensuring that you can't
create new columns on the fly), look for true matrix classes. (One
exists in the standard library; see http://ruby-doc.org/stdlib/libdoc/matrix/rdoc/index.html
for more information. Also see the NArray class.)

another question I believe the answer is no but i want to confirm
can we have multi-dimensional hash? :slight_smile:

Of course, they are called hashes of hashes. For example:

  people = {
    :gavin => {
      :age => 34,
      :sex => :male
    },
    :lisa => {
      :age => 33,
      :sex => female
    }
  }

  p people[ :lisa ][ :age ]
  #=> 33

Here's a Hash that automatically creates new hashes for each key you
try to access (specifically 1-level deep for a '2-dimensional' hash):

  people = Hash.new{ |me,key| me[ key ] = {} }
  people[ :gavin ][ :age ] = 34
  people[ :gavin ][ :sex ] = :male
  people[ :fido ][ :species ] = :dog
  p people
  #=> {:gavin=>{:age=>34, :sex=>:male}, :fido=>{:species=>:dog}}

As you can see, again, there is no constraint on what sort of keys are
allowed at any level.

I hope this helps you see how:
a) The core classes of Ruby do not include a lot of very specialized
cases,
b) You can write any classes you want (and someone probably already
has)
c) If you don't require the program to ensure you don't go 'out of
bounds', you can use all sorts of nested objects to create what you
want.

···

On Oct 17, 4:53 am, Shuaib Zahda <shuaib.za...@gmail.com> wrote:

Dear Stefano
Thanks for the reply. The way you gave me is basically makes six rows
and unlimited number of columns
I want the other way aroud
basically I have this table

field | type | key | default | extra | null
name | string | yes | null | auto_increment| null
id | integer | .... .... . .. . . . . ..
address

basically is a small database structure

any idea? thanks

···

--
Posted via http://www.ruby-forum.com/.

Arrays in Ruby don't have a static length, you can append to them at will...

irb(main):001:0> anArry = Array.new
=>
irb(main):002:0> anArry << Array.new
=> []
irb(main):003:0> anArry << Array.new
=> [, ]
irb(main):004:0> anArry[0][0] = 1
=> 1
irb(main):005:0> anArry
=> [[1], ]
irb(main):006:0> anArry[0][1] = 2
=> 2
irb(main):007:0> anArry
=> [[1, 2], ]
irb(main):008:0> anArry[1][0] = 3
=> 3
irb(main):009:0> anArry[1][1] = 4
=> 4
irb(main):010:0> anArry
=> [[1, 2], [3, 4]]

MBL

···

On 10/17/07, Shuaib Zahda <shuaib.zahda@gmail.com> wrote:

Dear Stefano
Thanks for the reply. The way you gave me is basically makes six rows
and unlimited number of columns
I want the other way aroud
basically I have this table

field | type | key | default | extra | null
name | string | yes | null | auto_increment| null
id | integer | .... .... . .. . . . . ..
address

basically is a small database structure

any idea? thanks
--
Posted via http://www.ruby-forum.com/\.

Shuaib, If you want a simple database, you might consider SQLite, there is a ruby gem for it and you can use ORMs such as ActiveRecord too.

···

On Oct 17, 2007, at 8:31 AM, Shuaib Zahda wrote:

Dear Stefano
Thanks for the reply. The way you gave me is basically makes six rows
and unlimited number of columns
I want the other way aroud
basically I have this table

field | type | key | default | extra | null
name | string | yes | null | auto_increment| null
id | integer | .... .... . .. . . . . ..
address

basically is a small database structure

any idea? thanks
-- Posted via http://www.ruby-forum.com/\.

Dear Stefano
Thanks for the reply. The way you gave me is basically makes six rows and unlimited number of columns

Well, it depends on what dimension you view as row and column.

I want the other way aroud
basically I have this table

field | type | key | default | extra | null
name | string | yes | null | auto_increment| null
id | integer | .... .... . .. . . . . ..
address

basically is a small database structure

any idea? thanks

Why don't you just create a Struct with the six fields you have in mind and stuff those instances in an Array?

And what is a "multi dimensional hash"?

Kind regards

  robert

···

On 17.10.2007 15:31, Shuaib Zahda wrote:

Dear all
Thanks for the help, I managed to do it using Mr. Michael
Bevilacqua-Linn way. and it works

just to share with u the lines of code that make the two - dimensional
array.
note that the number of columns can be extended.

  columns = Array.new()
  columns << Array.new
  columns[i][0] = col[0]
  columns[i][1] = col[1]

Regarding the multidimensional hash what i meant is hash of hashes.
Thanks

···

--
Posted via http://www.ruby-forum.com/.

Sorry guys, I am very slow.
In conclusion. how would the following be represented in Ruby?
It is a 3x3 matrix.

  11 76 -34 31 -66 71 -1 63 34
Thank you

Victor

···

On 10/17/07, Shuaib Zahda <shuaib.zahda@gmail.com> wrote:

Dear all
Thanks for the help, I managed to do it using Mr. Michael
Bevilacqua-Linn way. and it works

just to share with u the lines of code that make the two - dimensional
array.
note that the number of columns can be extended.

  columns = Array.new()
  columns << Array.new
  columns[i][0] = col[0]
  columns[i][1] = col[1]

Regarding the multidimensional hash what i meant is hash of hashes.
Thanks
--
Posted via http://www.ruby-forum.com/\.

It depends on what you want to do. If you just want to represent it
as a nested array, you could...

my_matrix = [[11, 76, -34], [31, -66, 71], [-1 63 34]]

As you notice, this is still 2-dimensional.

For math type matrix functionality, there is the matrix standard library...

require 'matrix'

which includes methods that return a manipulated matrix (represented
by the Matrix object), like inverse, rank, determinant, algebraic
functions, etc. I believe you can also go back and forth between
nested arrays and Matrix objects using Matrix#to_a and
Matrix#(*rows). Somebody else might be able to fill you in better.

You can find documentation for that under the standard library docs at
http://www.ruby-doc.org.

hth,
Todd

···

On 10/19/07, Victor Reyes <victor.reyes@gmail.com> wrote:

Sorry guys, I am very slow.
In conclusion. how would the following be represented in Ruby?
It is a 3x3 matrix.

  11 76 -34 31 -66 71 -1 63 34
Thank you

I just wanted to play with Magic Squares and other multidimensional arrays.

Thank you for the info about matrix.

···

On 10/19/07, Todd Benson <caduceass@gmail.com> wrote:

On 10/19/07, Victor Reyes <victor.reyes@gmail.com> wrote:
> Sorry guys, I am very slow.
> In conclusion. how would the following be represented in Ruby?
> It is a 3x3 matrix.
>
> 11 76 -34 31 -66 71 -1 63 34
> Thank you

It depends on what you want to do. If you just want to represent it
as a nested array, you could...

my_matrix = [[11, 76, -34], [31, -66, 71], [-1 63 34]]

As you notice, this is still 2-dimensional.

For math type matrix functionality, there is the matrix standard
library...

require 'matrix'

which includes methods that return a manipulated matrix (represented
by the Matrix object), like inverse, rank, determinant, algebraic
functions, etc. I believe you can also go back and forth between
nested arrays and Matrix objects using Matrix#to_a and
Matrix#(*rows). Somebody else might be able to fill you in better.

You can find documentation for that under the standard library docs at
http://www.ruby-doc.org.

hth,
Todd