Multi-dimensional (like 2) arrays in Ruby

All of the replies say the same thing -- this is good.
My learning project for Ruby is implementing a turning grille cipher. I want to allocate a n*m matrix where n and m are read from stdin.

I have the n[] (the rows) array, no sweat. But the m part (the columns) is rather elusive.

Here's my latest code:

@m = Array.new(@rows)
@M = @m.each {|row| @m[row] = Array.new(@cols)}

It doesn't work, either... :frowning:

Try:

matrix = Array.new(@rows, Array.new(@cols))

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.11.08 at 18.29.35

···

On Sat, 9 Nov 2002 08:18:31 +0900, Ted wrote:

All of the replies say the same thing – this is good. My learning
project for Ruby is implementing a turning grille cipher. I want
to allocate a n*m matrix where n and m are read from stdin.

I have the n (the rows) array, no sweat. But the m part (the
columns) is rather elusive.

Here’s my latest code:

@m = Array.new(@rows)
@M = @m.each {|row| @m[row] = Array.new(@cols)}

“Ted” ted@datacomm.com writes:

All of the replies say the same thing – this is good.
My learning project for Ruby is implementing a turning grille cipher. I want to allocate a n*m matrix where n and m are read from stdin.

I have the n (the rows) array, no sweat. But the m part (the columns) is rather elusive.

Here’s my latest code:

@m = Array.new(@rows)
@M = @m.each {|row| #=> warning, ‘row’ is always nil here
@m[row] = #=> == @m[nil] which is invalid
Array.new(@cols)}

matrix=Array.new(@rows)
0.upto(@rows-1) {|i| matrix[i] = Array.new(@cols)}

YS.

Hi –

All of the replies say the same thing – this is good. My learning
project for Ruby is implementing a turning grille cipher. I want to
allocate a n*m matrix where n and m are read from stdin.

I have the n (the rows) array, no sweat. But the m part (the
columns) is rather elusive.

There’s a Matrix class shipped with Ruby – have a look at
lib/matrix.rb.

Here’s my latest code:

@m = Array.new(@rows)
@M = @m.each {|row| @m[row] = Array.new(@cols)}

It doesn’t work, either… :frowning:

Don’t forget that #each returns the receiver. In other words, in
this:

a = [1,2,3].each {|x| x * 20}

a ends up as [1,2,3], not as [20,40,60]. The transformation is
thrown away.

In your example, you’re trying to save the transformation explicitly
to the array that’s being transformed… but let Ruby do it for you
:slight_smile: For that purpose, you can use #map. In fact, you can just map a
series of arrays, based on the number of rows, directly into your
matrix:

m = (0…rows).map {|r| Array.new(cols)}

Another way to do much the same thing is:

m =
rows.times { m << Array.new(cols) }

David

···

On Sat, 9 Nov 2002, Ted wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi –

All of the replies say the same thing – this is good. My learning
project for Ruby is implementing a turning grille cipher. I want
to allocate a n*m matrix where n and m are read from stdin.

I have the n (the rows) array, no sweat. But the m part (the
columns) is rather elusive.

Here’s my latest code:

@m = Array.new(@rows)
@M = @m.each {|row| @m[row] = Array.new(@cols)}

Try:

matrix = Array.new(@rows, Array.new(@cols))

The problem with that is that each row ends up being the same
object:

cols,rows = 3,5
m = Array.new(rows, Array.new(cols))
m[1][1] = “hello”
p m[2][1] # => “hello”

I’m not sure whether there’s a plan afoot to enable a proc-calling
version of this (with which you could create a separate object each
time).

David

···

On Sat, 9 Nov 2002, Austin Ziegler wrote:

On Sat, 9 Nov 2002 08:18:31 +0900, Ted wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi –

···

On Sat, 9 Nov 2002 dblack@candle.superlink.net wrote:

m = (0…rows).map {|r| Array.new(cols)}

Whoops, see Gennady’s post where he does this without the extraneous
block variable :slight_smile:

m = (0…rows).map { Array.new(cols) }

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Austin Ziegler austin@halostatue.ca writes:

matrix = Array.new(@rows, Array.new(@cols))

Um… won’t work.
irb(main):027:0> matrix=Array.new(5, Array.new(6))
[[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, nil, nil, nil, nil]]irb(main):028:0> matrix[0].id
537855732
irb(main):029:0> matrix[1].id
537855732
irb(main):030:0> matrix[3].id
537855732

YS.

matrix = Array.new(@rows, Array.new(@cols))

The problem with that is that each row ends up being the same
object:

This may help:

@m = (0 … @rows).collect { Array.new @cols }

Gennady.

···

----- Original Message -----
From: dblack@candle.superlink.net
To: “ruby-talk ML” ruby-talk@ruby-lang.org
Sent: Friday, November 08, 2002 3:38 PM
Subject: Re: Multi-dimensional (like 2) arrays in Ruby

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav

Hi –

···

On Sat, 9 Nov 2002, Gennady F. Bystritsky wrote:

@m = (0 … @rows).collect { Array.new @cols }

You’d want the ‘…’ operator, though, assuming @rows contains the
number of rows you want (rather than the 0-based index of the top
row).

David


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav