Admito que soy un poco un novato rubí (escribiendo guiones de rake, ahora). En la mayoría de los idiomas, los constructores de copias son fáciles de encontrar. Media hora de búsqueda no lo encontró en rubí. Quiero crear una copia del hash para poder modificarlo sin afectar la instancia original.
Algunos métodos esperados que no funcionan según lo previsto:
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash
Mientras tanto, he recurrido a esta solución poco elegante
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
Hash
objetos simples , la respuesta proporcionada es buena. Si se trata de objetos similares a Hash que provienen de lugares que no controla, debe considerar si desea que la clase singleton asociada con el Hash esté duplicada o no. Ver stackoverflow.com/questions/10183370/…Respuestas:
El
clone
método es la forma estándar incorporada de Ruby para hacer una copia superficial :Tenga en cuenta que el comportamiento puede ser anulado:
fuente
Marshal.load(Marshal.dump(h))
.Como otros han señalado,
clone
lo harán. Tenga en cuenta queclone
un hash hace una copia superficial. Es decir:Lo que sucede es que las referencias de hash se están copiando, pero no los objetos a los que se refieren las referencias.
Si quieres una copia profunda, entonces:
deep_copy
funciona para cualquier objeto que se pueda ordenar. La mayoría de los tipos de datos integrados (Array, Hash, String, etc.) se pueden ordenar.Marshalling es el nombre de Ruby para la serialización . Con la clasificación, el objeto, con los objetos a los que se refiere, se convierte en una serie de bytes; esos bytes se usan para crear otro objeto como el original.
fuente
Marshal.load(Marshal.dump(o))
la copia profunda? Realmente no puedo entender lo que sucede detrás de escenah1[:a] << 'bar'
, modifica el objeto original (la cadena apuntada por h1 [: a]) pero si fuera a hacerloh1[:a] = "#{h1[:a]}bar"
, crearía un nuevo objeto de cadena, y apuntaríah1[:a]
a eso, mientrash2[:a]
es Todavía apunta a la cadena antigua (sin modificar).Si está utilizando Rails, puede hacer:
http://apidock.com/rails/Hash/deep_dup
fuente
Hash puede crear un nuevo hash a partir de un hash existente:
fuente
También soy un novato en Ruby y enfrenté problemas similares al duplicar un hash. Usa lo siguiente. No tengo idea de la velocidad de este método.
fuente
Como se menciona en la sección Consideraciones de seguridad de la documentación de Marshal ,
Aquí hay un ejemplo sobre cómo hacer clonación usando JSON en Ruby:
fuente
Uso
Object#clone
:(Confusamente, la documentación
clone
dice que esainitialize_copy
es la forma de anular esto, pero el enlace para ese método loHash
dirige a usted en sureplace
lugar ...)fuente
Dado que el método de clonación estándar conserva el estado congelado, no es adecuado para crear nuevos objetos inmutables basados en el objeto original, si desea que los nuevos objetos sean ligeramente diferentes al original (si le gusta la programación sin estado).
fuente
El clon es lento. Para el rendimiento probablemente debería comenzar con hash en blanco y fusionar. No cubre el caso de hashes anidados ...
fuente
Este es un caso especial, pero si está comenzando con un hash predefinido que desea obtener y hacer una copia, puede crear un método que devuelva un hash:
El escenario particular que tuve fue que tenía una colección de hashes de esquema JSON donde algunos hashes se construyeron a partir de otros. Inicialmente los estaba definiendo como variables de clase y me encontré con este problema de copia.
fuente
puede usar a continuación para copiar en profundidad los objetos Hash.
fuente
Dado que Ruby tiene un millón de formas de hacerlo, aquí hay otra forma de usar Enumerable:
fuente
Una forma alternativa de Deep_Copy que funcionó para mí.
Esto produjo una copia profunda ya que h2 se forma usando una representación de matriz de h1 en lugar de las referencias de h1.
fuente