2017-02-24 2 views
0

Ich arbeite derzeit in einer Methode, die innerhalb einer Klasse ist.Kopierte Array als Original

Ich habe versucht, meine Array duplizieren wie so:

fakearray = [] 
@puzzarray.each_index do |row| 
    fakearray << @puzzarray[row] 
end 

Und

fakearray = @puzzarray.clone 

aber wenn ich @puzzarray ausdruckt, bemerkte ich, dass sie alle Änderungen hält ich für die fakearray tat. Der Zweck für die fakearray war, es als ein Klon zu verwenden, um zu überprüfen, ob mein Code arbeitete, bevor es auf @puzzarray ausgeführt wurde, aber es behielt alle schlechten Änderungen trotzdem bei. Irgendwelche Vorschläge?

+1

Sie sollten nur in der Lage sein, zu 'dup' ein Array. 'fakearray = @ puzzarray.dup'. Sie können ihre 'object_id',' fakearray.object_id == @ puzzarray.object_id' überprüfen, um zu sehen, dass es sich um unterschiedliche Objekte handelt, wenn sie sich in unterschiedlichem Speicherplatz befinden und keine Interaktion haben. – Kris

Antwort

0

Überprüfen Sie diese Dokumentation für dup als eine Alternative zu Ihrer Wahl von clone: dup. In diesem Abschnitt im Link ist eine Beschreibung des Unterschieds zwischen clone und dup. Überprüfen Sie es und sehen Sie, ob dies Ihrer Situation hilft.

0

Mit activesupport Juwel Sie könnten #deep_dup verwenden:

a = ['asd'] 
deep_copy = a.deep_dup 
deep_copy[0] << 'dsa' #=> "asddsa" 
a #=> ["asd"] 

Sonst könnte man Marshal.load(Marshal.dump(a)):

deep_copy = Marshal.load(Marshal.dump(a)) 
deep_copy[0] << 'dsa' #=> "asddsa" 
a #=> ["asd"] 
+0

Ich kann keine Edelsteine ​​dafür verwenden. Ich bin immer noch verwirrt, wie Marshal ein Duplikat meines Arrays erstellt. Was wirklich alles ist, was ich will, ohne dass das Duplikat mein richtiges Array vermasselt. Ich weiß wirklich nicht einmal, warum das duplizierte Array in erster Linie wie das Original funktioniert. – jackneedshelp

+1

Zuerst wird 'Marshal.dump (a)' eine Kopie von 'a' in einen separaten Speicherbereich (einen Bytestrom) packen, wodurch die gesamte Datenstruktur effektiv dupliziert wird, aber die Struktur (als Bytestrom) verfälscht wird. Zweitens wird 'Marshal.load (~)' die gesamte Datenstruktur in eine neue Variable 'deep_copy' entpacken. Auf diese Weise haben Sie die gesamte Struktur in eine neue Variable dupliziert, die keine Beziehung zum Original hat. Sie müssen jedoch aufpassen, was Sie 'Marshal' sind. Einige Objekte können nicht korrekt behandelt werden. (Siehe: https://ruby-doc.org/core-2.2.2/Marshal.html) –

+1

Wenn Sie "duplicated array" sagen, verwenden Sie tatsächlich "clone", was der Spezifikation für "Object" entspricht states "Erzeugt eine flache Kopie von obj - die Instanzvariablen von obj werden kopiert, aber nicht die Objekte, auf die sie verweisen.". Eine "flache" Kopie gibt Ihnen ein anderes Objekt, das auf die gleichen Daten zeigt. Wenn Sie die Daten dieses neuen Objekts manipulieren, wird das Original geändert. Wie andere gesagt haben, wenn Sie den alten Zustand der Daten ändern und den alten Objekt-Zustand in Ruhe lassen wollen, ist 'Marshal'ling oder die Verwendung von' dup' der richtige Weg. –

0

Ich bin, dass @puzzarray erraten ist ein Array mit (Teil-) Arrays. Wenn das der Fall ist, dann wird dieser Code

tatsächlich ein neues Array erstellen, aber es enthält die gleichen Subarrays. Die Methode <<, entsprechend den Dokumenten, "schiebt das gegebene Objekt auf das Ende dieses Feldes". Das angegebene Objekt, keine Kopie. Dies sollte ein Mittel sein:

fakearray = [] 
@puzzarray.each_index do |row| 
    fakearray << @puzzarray[row].dup 
end 

Dies ist ein kürzerer Weg, um das gleiche zu erreichen:

fakearray = @puzzarray.map(&:dup) 
Verwandte Themen