Frage

Ich stehe vor etwas, das ich nicht vollständig verstehe.

Ich habe ein Array, dessen Elemente Arrays sind.

Also habe ich zwei verschachtelte Schleifen, in der inneren Schleife fülle ich mein inneres Array, dann fülle ich in der äußeren Schleife das äußere Array mit dem inneren Array.

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

Am Ende ist meine Matrix mit zwei Array gefüllt; Jedes Array enthält die in der letzten Iteration berechneten Werte. Wenn ich möchte, dass das erste Element in Matrix das erste berechnete Array enthält, muss ich das ARR -Objekt in jeder Schleife neu initialisieren. Es scheint also, dass die Zuordnung durch Referenz erfolgt, bis das ARR -Objekt "gereinigt" ist. Wenn ich hinzufüge

mat[m]=arr
arr=[]

Alle funktionieren wie erwartet: MAT [0] enthält das in der erste Schleife berechnete Array und MAT [1] das in der zweite Schleife berechnete Array.

Ist dies durch Design oder ist es ein unerwünschter Nebeneffekt? Dies geschieht nur, wenn ich Arrays als Array -Elemente zuweist. Wenn Sie ein Array mit einfachen Zeichenfolgenvariablen in einer Schleife füllen, geht alles wie erwartet.

Ich weiß, dass es eine gute Programmierpraxis ist, Objekte wiederzuverwenden, aber dieses Verhalten ist sowieso seltsam.

War es hilfreich?

Lösung

Ihr Problem ist, dass der Inhalt Ihrer ARR -Variablen mit jeder Iteration überschrieben wird: die arr[k] Überschreiben Sie, was auch immer dort ist. Die ARR -Variable muss stattdessen lokal zum Block sein:

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

Andere Tipps

Ich mag den Ansatz von Verwenden von Hashes anstelle von mehrdimensionalen Arrays.

Wie wäre es damit:

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

Dann mach:

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

Sie erhalten einen Hash, auf den Sie so zugreifen können:

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

Eine andere Möglichkeit, es zu tun:

(1..4).map{rand}.each_slice(2).to_a
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top