The complexity of changing the two-dimensional structure of a ruby

Sorry newbie question. I am trying to create a two-dimensional array in ruby ​​and initialize all its values ​​to 1. My code creates a two-dimensional array just fine, but cannot change any of its values.

Can someone 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 
+3
source share
4 answers

This is row.each do |column| The column variable is a copy of the value in row . You cannot edit its value in this 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 
+3
source

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

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

+1
source

you can create it like this:

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

column in your nested loop each 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 only change the value of the copy (which ceases to exist outside the block).

If you just need a two-dimensional array filled with 1 something simple, how this will work:

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

Pretty simple.


By the way, if you want to know how to change the elements of a two-dimensional array when you repeat it, here is one way (starting at 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 
-1
source

Source: https://habr.com/ru/post/1482032/


All Articles