Je suis un débutant. Jusqu'à présent, je suis en contact avec deux langues, rubis et python. J'ai également lu quelques essais sur les pointeurs C ++, j'ai eu un peu de confusion avec des objets de tableau et comment manipuler la valeur à l'intérieur. J'ai constaté que, y compris une marque d'exclamation dans la méthode, peut changer la matrice sans mission. Cependant, parfois ça ne le fait pas; J'apprécie que quelqu'un puisse expliquer la nature de la matrice, qu'est-ce qu'ils sont un lieu de stockage de valeurs ou sont-ils la collecte de valeurs? Plus spécifiquement, si je divisez les fonctions de rubis dans deux groupes: Celui qui peut modifier les valeurs de la matrice sans attribution directement, et ceux qui ont besoin d'affectation, pourriez-vous me donner quelques exemples de
Dans l'exemple suivant, je ne comprends pas pourquoi les valeurs de mon tableau initial sont modifiées. de
Voici mon exemple de code:
edges = [[[1, 2], [100, 200]], [[700, 400], [1000, 2000]]]
new_edges = Array.new(edges)
new_edges.map{|edge| edge.map{|point| point.insert(0, 808912)}}
edges
#=> [[[808912, 1, 2], [808912, 100, 200]], [[808912, 700, 400], [808912, 1000, 2000]]]
new_edges
#=> [[[808912, 1, 2], [808912, 100, 200]], [[808912, 700, 400], [808912, 1000, 2000]]]
3 Réponses :
Vous commencez avec
def deep_dup
new_arr = []
self.each do |ele|
if ele.is_a? Array
new_arr << ele.deep_dup
else
new_arr << ele
end
end
new_arr
end
Ruby n'a pas profond_dup code>. ActiveSupport fait (et donc rails fait aussi).
Oh, je viens de googler et j'ai mal interprété la documentation. Mon mauvais, je viens de voir #deep_dup, mais ça doit avoir été active et non rubis. En outre, votre solution est bien plus d'espace et de temps efficace, haha. Il suffit d'utiliser une méthode qui ne mute pas le tableau d'origine est beaucoup mieux que Deep_dupping l'original, puis utilisez des méthodes qui mutent.
Une manière un peu pirate de clone profonde un tableau sans utiliser de rails est marshal.load marshal.dump (my_array) code>. Marshal.Dump Code> Porte le tableau dans un format de chaîne, lequel marshal.load code> décompresse dans un tableau.
Votre code a les mêmes problèmes que cela serait en python: i.e. Vous transformez la matrice extérieure, mais les matrices internes ne sont maintenues que par référence, et la modification ainsi (par en rubis, au lieu d'utiliser insert code>) modifie la teneur en profondeur des deux bords code> et et new_edges code>. Ces types de problèmes sont très facilement compris en progressant de votre code avec Cet outil (malgré le nom, Cela fonctionne à la fois pour Python et Ruby). P> insert code>, qui modifie une matrice, vous pouvez utiliser + code>, qui fait Non: P> edges = [[[1, 2], [100, 200]], [[700, 400], [1000, 2000]]]
new_edges = edges.map { |edge| edge.map { |point| [808912] + point } }
# => [[[808912, 1, 2], [808912, 100, 200]], [[808912, 700, 400], [808912, 1000, 2000]]]
edges
# => [[[1, 2], [100, 200]], [[700, 400], [1000, 2000]]]
Merci. J'ai aussi trouvé une autre manière: 'new_edges = marshal.load (Marshal.dump (bords))' 'New_edges.map {| Point | point.insert (0, 808912)} '
Voici une situation plus générale qui illustre le problème que vous rencontrez et des moyens de la corriger. Supposons que nous ayons les tableaux imbriqués suivants: pour la lisibilité, j'ai supprimé les sept premiers chiffres de chacun des ID d'objet, qui dans tous les cas est créent maintenant un nouveau tableau à partir de A0 code>, a1 code>, a code> et bords code> avoir des identifiants d'objet uniques: p> 4833847 . Remarque bords [0] [1] [0] # => 3 code> et 3.Object_id # => 7 code>. Pour des raisons d'efficacité, des entiers (et certains autres objets rubis ont des identifiants d'objet fixes, petits, d'objets. P> Bords code> à l'aide de la méthode Array :: Nouveau : P> edges[0][1][0] = 3
edges
#=> [[[1, 2], [3, 4]]]
new_edges
#=> [[[1, 2], [5, 4]]]
On dirait que vous créez
NEW_EDGES CODE> TRAY deux fois. Une fois avec une array.new et deux fois avec de nouvelles_edges.map. Pourquoi le faites-vous de cette façon? Qu'est-il arrivé quand vous avez randonnée ce code dans le terminal?Existe-t-il une meilleure façon de le faire? Pourriez-vous me donner quelques suggestions, merci.
Well Array.New (bords) semble bien ... Mais quel est le problème? Vous devez inclure les résultats lorsque vous exécutez ce code, c'est-à-dire. message d'erreur ou sortie.
Duplicaté possible de Comment initialiser un tableau en une étape en utilisant Ruby?
Ce qu'il est initialement: [[[[[1, 2], [100, 200]], [[700, 400], [1000, 2000]]], ce que je veux: [[[808912, 1, 2], [ 808912, 100, 200]], [[808912, 700, 400], [808912, 1000, 2000]]], et je dois utiliser la valeur initiale plus tard
Les premiers puts résultent du terminal sont les suivants: [[[[808912, 100, 200], [808912, 100, 200]] [[808912, 700, 400], [808912, 1000, 2000]]]. Le deuxième résultat est le suivant: [[[[808912, 1, 2], [808912, 100, 200]] [[808912, 700, 400], [808912, 1000, 2000]]]
Laissez-nous Continuez cette discussion dans le chat .