Skip to content

Creating multidimensional Arrays in Ruby with 1 line

Recently I thought I’d discovered a pretty cool trick:

array_2d = Array.new(w, Array.new(0))

Turns out….not so much. The new Array looks correct:

pp array_2d

[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0]]

The problem came when I needed to actually start setting values:

w.times do |i|
  w.times do |j|
    array_2d[i][j] = (i*w)+j
  end
end

output (???):
[[20, 21, 22, 23, 24],
 [20, 21, 22, 23, 24],
 [20, 21, 22, 23, 24],
 [20, 21, 22, 23, 24],
 [20, 21, 22, 23, 24]]

This is where understanding how ruby works with its objects under the hood comes in useful. It turns out this way of initializing a multidimensional array leads to the rows all being the same object, rather than multiple instances of Array. Therefore manipulating them sets the value in all rows (find out more about the object_id method here):

array_2d.map { |row| row.object_id }

output:
[4545360, 4545360, 4545360, 4545360, 4545360]

Still, there’s an easy fix, you can just do this instead:

array_2d_better = Array.new(w).map { Array.new(w, 0) }

pp array_2d_better.map { |x| x.object_id }

output:
  [5506840, 5506820, 5506800, 5506780, 5506760]
Published inRuby

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *