kefahi  
                
               
                 
              
                  
                    March 6, 2022,  1:04pm
                   
                   
              1 
               
             
            
              Hello, 
I’m puzzled with the outcome of this simple code. 
The intention is to assign a unique number in each “cell”:
heirs = Array.new(2, Array.new(2, 0_i32))
(0..3).each { |i|
  heirs[i//2][i%2] = i+1
}
p! heirs
 
This is the result I get (based on Crystal 1.3.2)
heirs # => [[3, 4], [3, 4]]
 
The expected outcome should have been:
heirs # => [[1, 2], [3, 4]]
 
Any clue on my wrong doing?
Thanks!
             
            
               
               
               
            
            
           
          
            
              
                kefahi  
                
               
              
                  
                    March 6, 2022,  1:11pm
                   
                   
              2 
               
             
            
              Update: My guess is that only one sub-array is created instead of two. 
But, if so, how do I instruct crystal to create two sub-arrays?
             
            
               
               
               
            
            
           
          
            
              
                hholst  
                
               
              
                  
                    March 6, 2022,  1:14pm
                   
                   
              3 
               
             
            
              Why can’t this library support dense array notation like numpy? The representation of matrices as a list of lists is beyond inefficient it should be illegal.
Have a look at this instead if you want to work with real matrices
PS. This works right? It creates an Array of two (distinct) arrays. You’re only calling the .new method once in the inner section so there is just one inner Array - just as you already described.
heir = [[0,0],[0,0]]
(0..3).each { |i|
  heirs[i//2][i%2] = i+1
}
 
             
            
               
               
              1 Like 
            
            
           
          
            
            
              
Update: My guess is that only one sub-array is created instead of two.
 
That’s exactly the reason. When you pass a value to Array.new(size, value), that value is used to initialize every position.
You can use the block version to use different values in every position. Try this:
heirs = Array.new(2) { Array.new(2, 0_i32) }
(0..3).each { |i|
  heirs[i//2][i % 2] = i + 1
}
p! heirs
 
You can also use the block version to directly initialize the array with the values you need:
heirs = Array.new(2) do |i|
  Array.new(2) do |j|
    2*i + j + 1
  end
end
p! heirs
 
             
            
               
               
              3 Likes 
            
            
           
          
            
              
                kefahi  
                
               
              
                  
                    March 6, 2022,  1:44pm
                   
                   
              6 
               
             
            
              Awesome! 
The block version is concise and makes sense. 
Thank you.