Pergunta

Estou enfrentando algo que não entendo completamente.

Eu tenho um array cujos elementos são arrays.

Então, eu tenho dois loops aninhados, no loop interno, preenchendo minha matriz interna e depois no loop externo, encher a matriz externa com a matriz interna.

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

No final minha matriz é preenchida com dois arrays;cada array contém os valores calculados na última iteração.Se eu quiser que o primeiro elemento da matriz contenha o primeiro array computado, tenho que reinicializar o objeto arr em cada loop.Portanto, parece que a atribuição é feita por referência até que o objeto arr seja "limpo".Se eu adicionar

mat[m]=arr
arr=[]

tudo funciona conforme o esperado:mat[0] conterá o array calculado no primeiro loop e mat[1] conterá o array calculado no segundo loop.

Isso é intencional ou é um efeito colateral indesejado?Isso acontecerá apenas se eu atribuir matrizes como elementos de matriz.Se preencher um array com variáveis ​​​​de string simples em um loop, tudo correrá conforme o esperado.

Eu sei que é uma boa prática de programação evitar a reutilização de objetos, mas esse comportamento é estranho de qualquer maneira.

Foi útil?

Solução

Seu problema é que o conteúdo da sua variável arr está sendo substituído a cada iteração:o arr[k] substitui tudo o que já está lá.A variável arr precisa ser local para o bloco:

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

Outras dicas

Eu gosto da abordagem de usando hashes em vez de matrizes multidimensionais.

Que tal agora:

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

Então faça:

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

Você receberá um hash, que pode ser acessado assim:

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

Outra maneira de fazer isso:

(1..4).map{rand}.each_slice(2).to_a
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top