2 dimensional array

Discussion in 'Ruby' started by Shuaib Zahda, Oct 17, 2007.

  1. Shuaib Zahda

    Shuaib Zahda Guest

    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? :)

    any one has any idea to share
    Regards
    Shuaib
    --
    Posted via http://www.ruby-forum.com/.
     
    Shuaib Zahda, Oct 17, 2007
    #1
    1. Advertising

  2. Alle mercoled=C3=AC 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 =3D [][] # did not work
    > array =3D [[],[]] # 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? :)
    >
    > any one has any idea to share
    > Regards
    > Shuaib


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

    a =3D Array.new(6){[]}

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

    You can store entries like this:

    a[2][3] =3D 1

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

    Of course, this approach allows you to have columns with different sizes. F=
    or=20
    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.=20
    If you want to avoid this, you can wrap the 2d array in a class:

    class Array2D

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

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

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

    def []=3D(col, row, value)
    raise IndexError if col >=3D @data.size or row >=3D @data[0].size
    @data[col][row]=3Dvalue
    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 =3D Array2D.new 3, :a
    3.times{a.append_row}
    a[0, 0] =3D :b
    a[1, 2] =3D :c
    p a[0]
    p a[1]
    p a[2]

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

    Stefano
     
    Stefano Crocco, Oct 17, 2007
    #2
    1. Advertising

  3. Shuaib Zahda

    Shuaib Zahda Guest

    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 Zahda, Oct 17, 2007
    #3
  4. Shuaib Zahda

    Phrogz Guest

    On Oct 17, 4:53 am, Shuaib Zahda <> wrote:
    > 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? :)


    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.
     
    Phrogz, Oct 17, 2007
    #4
  5. Shuaib Zahda

    John Joyce Guest

    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/.
    >


    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.
     
    John Joyce, Oct 17, 2007
    #5
  6. On 17.10.2007 15:31, Shuaib Zahda wrote:
    > 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
     
    Robert Klemme, Oct 17, 2007
    #6
  7. Shuaib Zahda

    Shuaib Zahda Guest

    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[0] = col[0]
    columns[1] = col[1]

    Regarding the multidimensional hash what i meant is hash of hashes.
    Thanks
    --
    Posted via http://www.ruby-forum.com/.
     
    Shuaib Zahda, Oct 18, 2007
    #7
  8. Shuaib Zahda

    Todd Benson Guest

    On 10/19/07, Victor Reyes <> 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
     
    Todd Benson, Oct 19, 2007
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alf P. Steinbach
    Replies:
    0
    Views:
    455
    Alf P. Steinbach
    Aug 18, 2003
  2. John Harrison
    Replies:
    4
    Views:
    6,958
    Default User
    Aug 19, 2003
  3. Icosahedron
    Replies:
    8
    Views:
    689
    Vivek
    Aug 21, 2003
  4. Venkat
    Replies:
    4
    Views:
    1,019
    Venkat
    Dec 5, 2003
  5. Wirianto Djunaidi
    Replies:
    2
    Views:
    230
    Wirianto Djunaidi
    Apr 29, 2008
Loading...

Share This Page