Ich gebe zu, dass ich ein bisschen ein Rubin-Neuling bin (jetzt schreibe ich Rake-Skripte). In den meisten Sprachen sind Kopierkonstruktoren leicht zu finden. Eine halbe Stunde Suche fand es nicht in Rubin. Ich möchte eine Kopie des Hashs erstellen, damit ich ihn ändern kann, ohne die ursprüngliche Instanz zu beeinflussen.
Einige erwartete Methoden, die nicht wie beabsichtigt funktionieren:
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash
In der Zwischenzeit habe ich auf diese unelegante Problemumgehung zurückgegriffen
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
Hash
Objekten arbeiten, ist die Antwort gut. Wenn Sie mit Hash-ähnlichen Objekten arbeiten, die von Orten stammen, die Sie nicht kontrollieren, sollten Sie überlegen, ob die dem Hash zugeordnete Singleton-Klasse dupliziert werden soll oder nicht. Siehe stackoverflow.com/questions/10183370/…Antworten:
Die
clone
Methode ist Rubys Standardmethode für die Erstellung einer flachen Kopie :Beachten Sie, dass das Verhalten möglicherweise überschrieben wird:
quelle
Marshal.load(Marshal.dump(h))
.Wie andere darauf hingewiesen haben,
clone
wird es tun. Beachten Sie, dassclone
ein Hash eine flache Kopie erstellt. Das heißt:Was passiert ist, dass die Referenzen des Hashs kopiert werden, aber nicht die Objekte, auf die sich die Referenzen beziehen.
Wenn Sie eine tiefe Kopie wünschen, dann:
deep_copy
funktioniert für jedes Objekt, das gemarshallt werden kann. Die meisten integrierten Datentypen (Array, Hash, String usw.) können gemarshallt werden.Marshalling ist Rubys Name für Serialisierung . Beim Marshalling wird das Objekt - mit den Objekten, auf die es sich bezieht - in eine Reihe von Bytes konvertiert. Diese Bytes werden dann verwendet, um ein anderes Objekt wie das Original zu erstellen.
quelle
Marshal.load(Marshal.dump(o))
tief kopiert? Ich kann nicht wirklich verstehen, was hinter den Kulissen passierth1[:a] << 'bar'
das ursprüngliche Objekt ändern (die Zeichenfolge, auf die h1 [: a] zeigt), aber wenn Sie diesh1[:a] = "#{h1[:a]}bar"
stattdessen tun würden, ein neues Zeichenfolgenobjekt erstellen und darauf zeigen würdenh1[:a]
, während esh2[:a]
ist zeigt immer noch auf die alte (unveränderte) Zeichenfolge.Wenn Sie Rails verwenden, können Sie Folgendes tun:
http://apidock.com/rails/Hash/deep_dup
quelle
Hash kann aus einem vorhandenen Hash einen neuen Hash erstellen:
quelle
Ich bin auch ein Neuling bei Ruby und hatte ähnliche Probleme beim Duplizieren eines Hashs. Verwenden Sie Folgendes. Ich habe keine Ahnung von der Geschwindigkeit dieser Methode.
quelle
Wie im Abschnitt "Sicherheitsüberlegungen" der Marshal-Dokumentation erwähnt ,
Hier ist ein Beispiel zum Klonen mit JSON in Ruby:
quelle
Verwendung
Object#clone
:(Verwirrenderweise heißt es in der Dokumentation zu
clone
, dass diesinitialize_copy
der Weg ist, dies zu überschreiben, aber der Link für diese Methode inHash
verweist Siereplace
stattdessen auf ...)quelle
Da die Standardklonmethode den eingefrorenen Zustand beibehält, eignet sie sich nicht zum Erstellen neuer unveränderlicher Objekte auf der Grundlage des Originalobjekts, wenn Sie möchten, dass sich die neuen Objekte geringfügig vom Original unterscheiden (wenn Sie zustandslose Programmierung wünschen).
quelle
Klon ist langsam. Für die Leistung sollte wahrscheinlich mit leerem Hash beginnen und zusammenführen. Deckt nicht den Fall verschachtelter Hashes ab ...
quelle
Dies ist ein Sonderfall. Wenn Sie jedoch mit einem vordefinierten Hash beginnen, von dem Sie eine Kopie erstellen möchten, können Sie eine Methode erstellen, die einen Hash zurückgibt:
Das besondere Szenario, das ich hatte, war, dass ich eine Sammlung von JSON-Schema-Hashes hatte, in denen einige Hashes aus anderen aufgebaut waren. Ich habe sie ursprünglich als Klassenvariablen definiert und bin auf dieses Kopierproblem gestoßen.
quelle
Sie können unten verwenden, um Hash-Objekte tief zu kopieren.
quelle
Da Ruby über eine Million Möglichkeiten verfügt, können Sie Enumerable auf folgende Weise verwenden:
quelle
Alternativer Weg zu Deep_Copy, der für mich funktioniert hat.
Dies erzeugte eine deep_copy, da h2 unter Verwendung einer Array-Darstellung von h1 anstelle der Referenzen von h1 gebildet wird.
quelle