开发者

difficulty modifying two dimensional ruby array

Excuse the newbie question. I'm trying to create a two dimensional array in ruby, and initialise all its values to 1. My code is creating the two dimensional array just fine, but fails to modify any of its values.

开发者_JS百科

Can anyone explain what I'm doing wrong?

  def mda(width,height)
     #make a two dimensional array
     a = Array.new(width)
     a.map! { Array.new(height) }

     #init all its values to 1
     a.each do |row|
       row.each do |column|
          column = 1
       end
     end
     return a
  end


It the line row.each do |column| the variable column is the copy of the value in row. You can't edit its value in such way. You must do:

def mda(width,height)
  a = Array.new(width)
  a.map! { Array.new(height) }
  a.each do |row|
    row.map!{1}
  end
  return a
end

Or better:

def mda(width,height)
  a = Array.new(width)
  a.map! { Array.new(height) }

  a.map do |row|
    row.map!{1}
  end
end

Or better:

def mda(width,height)
  a = Array.new(width){ Array.new(height) }
  a.map do |row|
    row.map!{1}
  end
end

Or better:

def mda(width,height)
  Array.new(width) { Array.new(height){1} }
end


each passes into the block parameter the value of each element, not the element itself, so column = 1 doesn't actually modify the array.

You can do this in one step, though - see the API docs for details on the various forms of Array#new. Try a = Array.new(width) {|i| Array.new(height) {|j| 1 } }


you can create it like this?

a=Array.new(width) { Array.new(height,1) }


column in your nested each loop is a copy of the value at that place in the array, not a pointer/reference to it, so when you change its value you're only changing the value of the copy (which ceases to exist outside the block).

If you just want a two-dimensional array populated with 1s something as simple as this will work:

def mda(width,height)
  [ [1] * width ] * height
end

Pretty simple.


By the way, if you want to know how to modify the elements of a two-dimensional array as you're iterating over it, here's one way (starting from line 6 in your code):

 #init all its values to 1
 a.length.times do |i|
   a[i].length.times do |j|
     a[i][j] = 1
   end
 end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜