Comment puis-je copier une table de hachage en Ruby?
Je vais vous avouer que je suis un peu d'un rubis débutant (écrit râteau scripts, maintenant). Dans la plupart des langues, de copier les constructeurs sont faciles à trouver. Une demi-heure de recherche ne la trouverez pas en ruby. Je veux créer une copie de la table de hachage afin que je puisse le modifier sans affecter l'instance d'origine.
Certains attendent des méthodes qui ne fonctionnent pas comme prévu:
h0 = { "John"=>"Adams","Thomas"=>"Jefferson","Johny"=>"Appleseed"}
h1=Hash.new(h0)
h2=h1.to_hash
Dans l'intervalle, j'ai eu recours à cette solution peu élégante
def copyhash(inputhash)
h = Hash.new
inputhash.each do |pair|
h.store(pair[0], pair[1])
end
return h
end
- Si vous êtes aux prises avec la plaine
Hash
objets, la réponse est bonne. Si vous êtes aux prises avec de Hachage comme des objets qui viennent d'endroits que vous n'avez pas de contrôle que vous devriez considérer si vous voulez le singleton classe associée à la valeur de Hachage dupliqué ou pas. Voir stackoverflow.com/questions/10183370/...
Vous devez vous connecter pour publier un commentaire.
La
clone
méthode est de Ruby standard, intégré dans la façon de faire un peu profond, la copie:Noter que le comportement peut être remplacée:
Marshal.load(Marshal.dump(h))
.Hash#deep_dup
. Voir apidock.com/rails/Hash/deep_dupclone
par opposition àdup
? Avez-vous besoin de copier la classe singleton dans ce cas? stackoverflow.com/questions/10183370/...Comme d'autres l'ont souligné,
clone
de le faire. Sachez queclone
de hachage fait une copie superficielle. C'est-à-dire:Ce qui se passe est que le hachage de références sont en train d'être copié, mais pas les objets que les références se rapportent à l'.
Si vous voulez une copie en profondeur alors:
deep_copy
fonctionne pour n'importe quel objet qui peut être mobilisé. La plupart des types de données intégrés (Tableau, Hachage, de la Corde, &c.) peut être muselé.De triage est Ruby nom pour la sérialisation. Avec le regroupement, l'objet, avec les objets qu'il désigne--est converti en une série d'octets; ces octets sont ensuite utilisées pour créer un autre objet, comme l'original.
Marshal.load(Marshal.dump(o))
profonde de la copie? Je ne peux pas vraiment comprendre ce qui se passe en coulissesh1[:a] << 'bar'
vous modifiez l'objet d'origine (la chaîne de caractères pointée par h1[:a]), mais si vous le faitesh1[:a] = "#{h1[:a]}bar"
au lieu de cela, vous devez créer un nouvel objet de type string, et le point deh1[:a]
à qui, tout enh2[:a]
pointe toujours vers l'ancien (non modifié) à la chaîne.Marshal.load
est pas fiable, et une bonne avertissement pour garder à l'esprit. Dans ce cas, l'entrée à elle vient deMarshal.dump
dans notre propre processus. Je pense queMarshal.load
est en sécurité dans ce contexte.Si vous êtes à l'aide de Rails que vous pouvez faire:
http://apidock.com/rails/Hash/deep_dup
De hachage peut créer une nouvelle table de hachage à partir d'un hash:
Je suis aussi un débutant de Ruby et j'ai fait face à des problèmes similaires dans la duplication d'un hachage. Utilisation suivantes. J'ai pas d'idée sur la vitesse de cette méthode.
Comme mentionné dans Considérations relatives à la sécurité section du Maréchal de la documentation,
Voici un exemple sur la façon de faire du clonage en utilisant JSON en Ruby:
Utilisation
Objet#clone
:(Confusion, la documentation de
clone
dit queinitialize_copy
est le moyen de remplacer cette, mais le lien pour la méthode dansHash
vous dirige versreplace
à la place...)vous pouvez utiliser ci-dessous pour copie en profondeur de Hachage objets.
Depuis la norme méthode de clonage préserve l'état congelé, il n'est pas adapté pour la création de nouveaux objets immuables en se basant sur l'objet d'origine, si vous souhaitez que les nouveaux objets de l'être légèrement différent de l'original (si vous aimez les apatrides de programmation).
Clone est lente. Pour le rendement devrait probablement commencer avec un blanc de fusion et de hachage. Ne couvre pas les cas d'imbrication des hachages...
Depuis Ruby a un million de façons de le faire, voici une autre façon en utilisant Énumérable:
C'est un cas particulier, mais si vous êtes débutant avec un prédéfini de hachage que vous voulez prendre et en faire une copie, vous pouvez créer une méthode qui retourne une valeur de hachage:
Le scénario que j'avais était que j'avais une collection de JSON-schéma de hachages où certains hachages construite hors les autres. J'ai d'abord été définis comme des variables de classe et a couru dans cette copie.
Autre façon de Deep_Copy qui a fonctionné pour moi.
Ce produit un deep_copy depuis h2 est formé à l'aide d'un tableau de représentation de h1 plutôt que h1 références.