2016-05-07 18 views
5

sto lavorando sui problemi degli array delineati nella http://prepwork.appacademy.io/mini-curriculum/array/Rubino -> Scrittura Array 2D

Sto cercando di creare la funzione, my_transpose, che prende in una matrice e restituisce la sua trasposizione.

Sono molto confuso riguardo alla scrittura in un array 2D! Ecco un codice - snippet che evidenzia la mia confusione.

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]] 

Perché la modifica alle colonne [0] [0] modifica tutte e tre le variabili? Non dovrebbe semplicemente cambiare la prima cella nella prima fila?

risposta

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

Qui, Array.new(3) è chiamato una volta, e le tre sub-array di columns effettivamente riferimento a questo stesso Array oggetto. Controllare il loro object_id:

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

Ecco perché la modifica columns[0][0] rende columns[1][0] e columns[2][0] modificato pure.


Utilizzare questo invece:

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

Buona risposta, ma potrebbe valere la pena di spiegare brevemente * perché * la tua soluzione funziona. –

+0

Grazie! Perfezionare! – bmillsiv

3

@YuHao ha spiegato che è necessario:

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

In realtà, è possibile espandere che un po 'per creare il tuo metodo di trasposizione:

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]] 

Vedi Array::new.

+0

Wow, molto elegante. Mi piace molto. Grazie! – bmillsiv