2016-05-07 12 views
5

pracuję nad problemami przedstawionymi w tablicy http://prepwork.appacademy.io/mini-curriculum/array/Ruby -> Zapis do 2D tablice

Próbuję utworzyć funkcję, my_transpose, który odbywa się w matrycy i zwraca jej transpozycję.

Jestem bardzo zdezorientowany pisaniem do tablicy 2D! Oto fragment kodu, który podkreśla moje zamieszanie.

rows = [ 
    [0, 1, 2], 
    [3, 4, 5], 
    [6, 7, 8] 
    ] 

columns = Array.new(3 , Array.new(3)) 
puts columns.to_s #Output is a 3 x 3 array filled with nil 
columns[0][0] = 0 
puts columns.to_s #Output is [[0,nil,nil], [0,nil,nil], [0,nil,nil]] 

Dlaczego modyfikacja kolumn [0] [0] zmienia wszystkie trzy zmienne? Czy nie powinna zmienić pierwszej komórki w pierwszym rzędzie?

Odpowiedz

7
columns = Array.new(3 , Array.new(3)) 

Tutaj Array.new(3) nazywa się raz, a trzy sub-macierze columns rzeczywiście odniesienie do niniejszej samym Array obiektu. Sprawdź ich object_id:

columns[0].object_id 
# => 70296096047460 
columns[1].object_id 
# => 70296096047460 
columns[2].object_id 
# => 70296096047460 

Dlatego modyfikując columns[0][0] sprawia columns[1][0] i columns[2][0] zmodyfikowano również.


Użyj tego zamiast:

columns = Array.new(3) {Array.new(3)} 
+1

Dobra odpowiedź, ale warto krótko wyjaśnić, * dlaczego * Twoje rozwiązanie działa. –

+0

Dzięki! Idealny! – bmillsiv

3

@YuHao wyjaśnił, że potrzebne są:

Array.new(3) { Array.new(3) } 

W rzeczywistości, można poszerzyć że lekko stworzyć metodę transpozycji:

def my_transpose(arr) 
    Array.new(arr.size) { |i| Array.new(arr.size) { |j| arr[j][i] } } 
end 

my_transpose(rows) 
    #=> [[0, 3, 6], 
    # [1, 4, 7], 
    # [2, 5, 8]] 

Zobacz Array::new.

+0

Wow, bardzo elegancki. Bardzo to lubię. Dziękuję Ci! – bmillsiv