Iteration question

Dear all:

This is my code:

data = Array.new(5,[])
0.upto(4) do |i|
data[i].push(i)
end

p data

the output is :
[[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0,
1, 2, 3, 4]]

I am so confused why the output is not that showed below
[[0],[1],[2],[3],[4]]

On Mar 23, 7:20pm, Rimantas L. [email protected] wrote:

end
p data

In this case it is the same as

data = Array.new(5) {|index| [index]}
=> [[0], [1], [2], [3], [4]]

Regards,
Rimantas
http://rimantas.com/

Alternate way of doing the same thing:

data = []
0.upto(4) { |i| data << [i] }

regards,
bbiker

data = Array.new(5,[])
This gives you array with five references to the same array object:

ruby-1.9.2-p0 :036 > data = Array.new(5,[])
=> [[], [], [], [], []]

ruby-1.9.2-p0 :037 > data[0].object_id
=> 2156232780
ruby-1.9.2-p0 :038 > data[1].object_id
=> 2156232780

0.upto(4) do |i|
data[i].push(i)
no matter where you push you are still pushing to the same single array

What you want probably is:

data = Array.new(5) {[]}
0.upto(4) do |i|
data[i].push(i)
end
p data

In this case it is the same as

data = Array.new(5) {|index| [index]}
=> [[0], [1], [2], [3], [4]]

Regards,
Rimantas

From the docs:

Array.new(size=0, obj=nil)
Array.new(array)

Returns a new array. In the first form, the new array is empty. In the
second it is created with size copies of obj (that is, size references
to the same obj).

There is actually a mistake in the docs. The first two forms of new()
should be in this order:

Array.new(array)
Array.new(size=0, obj=nil)

Returns a new array. In the first form, the new array is empty. In the
second it is created with size copies of obj (that is, size references
to the same obj).

See the last part in parentheses? It’s a stupid feature of ruby, and
that behaviour must have been created by Matz to trip up
beginners. It should work as you expected.

Thanks for your kindly reply.

On Thu, Mar 24, 2011 at 2:20 AM, bbiker [email protected] wrote:

=> 2156232780
data[i].push(i)
http://rimantas.com/

Alternate way of doing the same thing:

data = []
0.upto(4) { |i| data << [i] }

Even simpler

irb(main):001:0> data = Array.new(5) {|i| [i]}
=> [[0], [1], [2], [3], [4]]
irb(main):002:0> data = Array.new(5) {|*a| a}
=> [[0], [1], [2], [3], [4]]
irb(main):003:0> data = 5.times.map {|i| [i]}
=> [[0], [1], [2], [3], [4]]

Kind regards

robert