Domanda

Sto affrontando qualcosa che non capisco completamente.

Ho un array i cui elementi sono array.

Quindi ho due anelli nidificati, nel ciclo interno riempirò il mio array interno, quindi nel ciclo esterno riempirò l'array esterno con l'array interno.

arr=[]
mat=[]
for m in (0..1)
  for k in (0..1)
    arr[k]=rand.to_s
  end
  mat[m]=arr
end

Alla fine la mia matrice è piena di due array; Ogni array contiene i valori calcolati nell'ultima iterazione. Se voglio che il primo elemento in matrice contenga il primo array calcolato, devo reinizializzare l'oggetto ARR ad ogni ciclo. Quindi sembra che l'assegnazione sia effettuata per riferimento fino a quando l'oggetto ARR non viene "pulito". Se aggiungo

mat[m]=arr
arr=[]

Tutte le opere come previsto: Mat [0] conterranno l'array calcolato nel primo loop e Mat [1] conterrà l'array calcolato nel secondo ciclo.

È questo per design o è un effetto collaterale indesiderato? Questo sta accadendo solo se assegno array come elementi di array. Se riempire un array con semplici variabili di stringa in un ciclo va tutto come previsto.

So che è una buona pratica di programmazione evitare di riutilizzare gli oggetti, ma questo comportamento è comunque strano.

È stato utile?

Soluzione

Il tuo problema è che il contenuto della tua variabile ARR è sovrascritto da ogni iterazione: il arr[k] sovrascrive tutto ciò che c'è già lì dentro. La variabile ARR deve invece essere locale al blocco:

mat = []
2.times do             # avoid for... use iterators instead
  row = []
  2.times do 
    row << rand.to_s
  end
  mat << row
end

Altri suggerimenti

Mi piace l'approccio di Usando hash invece di array multidimensionali.

Cosa ne pensi di questo:

def creat­e_matrix x, y, conte­nt = nil, &block
  rows = (0...x­).to_a
  cols = (0...y­).to_a
  indices = rows.­product cols
  matrix = {}
  indices.ea­ch { |inde­x| matri­x[index] = ( block­_given? ? yield­( index ) : conte­nt ) }
  matrix
end

Quindi fa:

matrix = create_matrix( 2, 2 ) { rand.to_s }

Otterrai un hash, che puoi accedere in questo modo:

matrix[[0, 1]] #note the double brackets

Un altro modo di farlo:

(1..4).map{rand}.each_slice(2).to_a
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top